Search code examples
pythondjangodjango-modelsdjango-admin

How can i auto fill a field and make it readonly in django admin


I want the created_by field to be filled automatically with the email of the current admin who is logged in and it should be read only field

I tried this:

admin.py

from django.contrib import admin
from support.models import Ticket

class TicketAdmin(admin.ModelAdmin):

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.base_fields['created_by'].initial = request.user
        return form

    def save_model(self, request, obj, form, change):
        if not obj.created_by:
            obj.created_by = request.user
        super().save_model(request, obj, form, change)


admin.site.register(Ticket, TicketAdmin)

I'm still able to edit the field and able to select other email addresses from a dropdown

model.py

class Ticket(models.Model):

    
    PRIORITY = (
        ("High", "high"),
        ("Medium", "medium"),
        ("Low", "low")
    )

    subject = models.CharField(max_length=255)
    body = models.TextField()
    priority = models.CharField(max_length=10,choices=PRIORITY)
    created_by = models.ForeignKey(Users, on_delete=models.CASCADE)

How can I implement it?


Solution

  • You can achive this by adding readonly_fields field to your ModelAdmin class:

    class TicketAdmin(admin.ModelAdmin):
        readonly_fields = ['created_by']
    
        def get_form(self, request, obj=None, **kwargs):
            form = super().get_form(request, obj, **kwargs)
            form.base_fields['created_by'].initial = request.user
            return form
    
        def save_model(self, request, obj, form, change):
            if not obj.created_by:
                obj.created_by = request.user
            super().save_model(request, obj, form, change)