Django Admin Tools for a model.
Published: 2022-07-30 17:52:49

In this tutorial you will learn about some built in tools for a model in django admin and how to apply them.

Suppose we have a model `Article`.

``` python
# models.py

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250)
    author = models.ForeignKey(User,
     on_delete=models.CASCADE,
     related_name='articles')
    body = models.TextField()
    published_on = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title
```

and we want following functionalities in our admin site for this model.

1. We don't want to show only the string representation of the `title` field of the model. We also want to represent `author` and `published_on` on the model entry.

2. We would like to create filters to sort the entries of the model.

3. We would like to have a search on the article entries page to find the desired entry.

4. We would like to prepopulate the `slug` field of the model in the basis of `title` field.

5. We would like to order the entries of the model in desired format.

to do so we have simple ways by grace of django 🦄.

**So let's get started!**

## 1. Representing many fields of a model in the admin site.

to do this we have to go in the `admin.py` file and create a `ModelAdmin` for our `Article` model and set a `list_display` list.

```python
# admin.py file
from django.contrib import admin
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    # displaying title, author and publish date.
    list_display = ['title', 'author', 'published_on']

admin.site.register(Article, ArticleAdmin)
```
now it will represent both `author` and `published_on` with the `title` of the model.

## 2. Creating filters to sort the model entries.

to do this we have to update our `ArticleAdmin` with `list_filter`.

```python
# admin.py file
from django.contrib import admin
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    # displaying title, author and publish date.
    list_display = ['title', 'author', 'published_on']
    # creating filter to sort the entries by publish date.
    list_filter = ['published_on',]

admin.site.register(Article, ArticleAdmin)
```

You will see a filter has occurred on the right side which you can use to filter the model entries by publish date.

You can also create a filter to sort the articles by the author but it's not a good approach because if the number of users increases the filter will become longer than the all entries.

## 3. Creating the search bar.

To create a search bar we just have to add 'search_fields' in our 'ArticleAdmin' class.

```python
# admin.py file
from django.contrib import admin
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    # displaying title, author and publish date.
    list_display = ['title', 'author', 'published_on']
    # creating filter to sort the entries by publish date.
    list_filter = ['published_on',]
    # creating the search bar.
    search_fields = ['title', 'body']

admin.site.register(Article, ArticleAdmin)
```
add the fields you want to search with in the `search_fields` list and you will see a search bar occurs on the top of the page.
You should not add a `foreignkey` field in this `search_fields` list because it does not support it.

## 4. Prepopulating slug in the basis of title.

We would like to get the `slug` automatically created in the basis of the `title` field. To do this we have to create a dictionary named `prepopulated_fields` in our `ArticleAdmin`.

```python
# admin.py file
from django.contrib import admin
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    # displaying title, author and publish date.
    list_display = ['title', 'author', 'published_on']
    # creating filter to sort the entries by publish date.
    list_filter = ['published_on',]
    # creating the search bar.
    search_fields = ['title', 'body']
    # prepopulating slug in the basis of title.
    prepopulated_fields = {'slug': ('title',)}

admin.site.register(Article, ArticleAdmin)
```
now the slug field will be automatically generated by the `title` field.

## 5. Ordering the article entries by the publish date.

to do this we just have to add the fields which we want to sort in the `ordering` list of the `ArticleAdmin`.

```python
# admin.py file
from django.contrib import admin
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    # displaying title, author and publish date.
    list_display = ['title', 'author', 'published_on']
    # creating filter to sort the entries by publish date.
    list_filter = ['published_on',]
    # creating the search bar.
    search_fields = ['title', 'body']
    # prepopulating slug in the basis of title.
    prepopulated_fields = {'slug': ('title',)}
    # ordering the model by the publish date.
    ordering = ['published_on',]

admin.site.register(Article, ArticleAdmin)
```
now you will see the option to order the articles by the publish date.

## Extra tip 💡

If we want to show any field of the model with some operation or calculation we can create a dedicated method in the model and then call the method name in the `list_display` of the `ModelAdmin`.

for example if we want to show the first 50 characters of the `body` of the `Article` we could do it like this:

```python 
# models.py

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250)
    author = models.ForeignKey(User,
     on_delete=models.CASCADE,
     related_name='articles')
    body = models.TextField()
    published_on = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

    def content(self):
        ''' represents the first 50 characters of the body 
        field.'''
        return f"{self.body[:50]} ..."
```
```python
# admin.py file
from django.contrib import admin
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    # displaying title, author and publish date.
    list_display = ['title', 'content', 'author', 'published_on']
    # creating filter to sort the entries by publish date.
    list_filter = ['published_on',]
    # creating the search bar.
    search_fields = ['title', 'body']
    # prepopulating slug in the basis of title.
    prepopulated_fields = {'slug': ('title',)}
    # ordering the model by the publish date.
    ordering = ['published_on',]

admin.site.register(Article, ArticleAdmin)
```
that's done.

Thank you for reading my article.