6

THE GOAL: Display a request-specific, read-only user_id on a django admin form when creating and updating a resource.

This display should be a readonly field (readonly, NOT disabled). The user_id displayed is derived from the requesting user (request.user) so the initial value is set from that.

Following this post, we should simply set it in the get_form method like so:

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

However, user is no longer on the base_fields when it is readonly. In fact, I can't find it anywhere. Any thoughts?

Other posts suggest on save, which I intend to do, but I need it to show on the form before then.

jbodily
  • 3,613
  • 2
  • 20
  • 21

1 Answers1

10

You are right that making the field readonly excludes it from the base_fields.As mentioned in the docs :

Any fields in this option (which should be a list or tuple) will display its data as-is and non-editable; they are also excluded from the ModelForm used for creating and editing.

You could have define a method for it just like list_display but since you need to set user from the request, we need to have the request object, which isn't available in the method.

So for your use case, we can use formfield_for_foreignkey method as :

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == 'lend_by':
        # setting the user from the request object
        kwargs['initial'] = request.user.id
        # making the field readonly
        kwargs['disabled'] = True
    return super().formfield_for_foreignkey(db_field, request, **kwargs)

Hope it helps.

djvg
  • 11,722
  • 5
  • 72
  • 103
not2acoder
  • 1,142
  • 11
  • 17
  • The field will still have add/change buttons. To remove these, we can extend `formfield_for_dbfield` (which calls `formfield_for_foreignkey`). It may also make sense to move the code above into that same method, as suggested [here](https://stackoverflow.com/a/54197083), to have it all in one place. – djvg Jan 15 '19 at 11:14
  • 2
    This doesn't work when create a new record since the `disabled` attribute makes the value of the field to be ignored when the form is submitted. – user2641103 Aug 06 '19 at 11:52