1

In Django's admin interface, there is a form, of a specific model that I want to be rendered in different ways depending if the logged user accessing this form is a normal user or an admin. It's working find except one HUGE thing: it get's mixed. For instance, the fields that should be editable by the admin are read-only, after I immediately prior to that had been logged in as a "normal" user. If I try the exactly same thing immediately after restarting the server, works fine and all fields are editable. I guess that somehow the user's sessions are get mixed up. How to handle this?

Here is waht I have:

In the App's admin.py:

151 class AdminForm(ModelForm):
152     class Meta:
153         model = PromotionalSlot
154         exclude = ['deal']
155 
156 class NormalUserForm(ModelForm):
157     class Meta:
158         model = PromotionalSlot
159         exclude = ['site']
160         
161 class PromotionalSlotAdmin(admin.ModelAdmin):
162      def get_form(self, request, obj=None, **kwargs):
163         if request.user.is_superuser:
164             return AdminForm
165         else:
166             self.readonly_fields = ['start_date','end_date','level','city','status']
167             return NormalUserForm· 
168
169 admin.site.register(models.PromotionalSlot, PromotionalSlotAdmin)

Thanks

rrb_bbr
  • 2,966
  • 4
  • 24
  • 26

1 Answers1

2

The problem is that your solution isn't thread safe. Django keeps the admin instance around and so the value you set to self.readonly_fields is used also for all subsequent requests in the thread. This is how you can make it thread safe:

class PromotionalSlotAdmin(admin.ModelAdmin):

    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return []
        else:
            return ['start_date', 'end_date', 'level', 'city', 'status']

    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            return AdminForm
        else:
            return NormalUserForm
Jakub Roztocil
  • 15,930
  • 5
  • 50
  • 52
  • That is really cool... I'm guess that I can do the exact same thing, for instance, with `list_display`, `exclude` or `list_filter` also, right? – rrb_bbr Jul 31 '11 at 01:48
  • Django provides many hooks on the admin class and you can read about the in the documentation (https://docs.djangoproject.com/en/dev/ref/contrib/admin/). What I find also very useful is to look through the source code: https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py. – Jakub Roztocil Jul 31 '11 at 01:53