Django Admin Making Model Fields Required

In this tutorial, we will learn how to make optional model fields required in Django admin to make sure that data for these fields are populated on the creation of new records from the Django admin interface.

 Understanding the Problem

Suppose you are working on a project that shares the User model with customers and Staff. In the models, there is a field phone_number that is not a required field because it’s optional for customers to share their contact information. However, you want to make sure that each staff user should have a phone number.

There are multiple ways to achieve this. If you are totally sure that new staff members will only get added through the Django admin. Then the simplest one would be to make the phone_number field required in the admin form.

Making Fields Required In Django Admin

I am gonna use the blog project for this example. Here we want to make the summary field required without making changes in models.

Django Admin Making Model Fields Required

models.py

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="blog_posts")
    updated_on = models.DateTimeField(auto_now=True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
    summary = models.CharField(max_length=500, null=True, blank=True)

    class Meta:
        ordering = ["-created_on"]

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        from django.urls import reverse
        return reverse("post_detail", kwargs={"slug": str(self.slug)})

This is how my admin.py file looks currently.

admin.py

@admin.register(Post)
class PostAdmin(SummernoteModelAdmin):
    list_display = ('title', 'slug', 'status', 'created_on')
    list_filter = ('status', 'created_on')
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}

In order to make the summary field required, we need to create a custom form for the Post model. I am making them on the same file you can do this on a separate forms.py file as well.

admin.py

class PostForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['summary'].required = True

    class Meta:
        model = Post
        fields = '__all__'

As intended we create the custom model form and in the __init__ method we made the summary field required.

Finally, we just need to set form = PostForm in PostAdmin.

This is how the admin.py file looks.

admin.py

class PostForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['summary'].required = True

    class Meta:
        model = Post
        fields = '__all__'


@admin.register(Post)
class PostAdmin(SummernoteModelAdmin):
    form = PostForm
    list_display = ('title', 'slug', 'status', 'created_on')
    list_filter = ('status', 'created_on')
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}

Save the files run the server and try to create a post without filling the summary field, you would receive a validation error like this.

 

Support Django Central

If you appreciate my work, or if it has helped you along your journey. It would mean a lot to me if you could write a message on my wall and share a cup of coffee (or tea) with me.
Buy Me a Coffee at ko-fi.com

Leave a Comment