Django Admin - Disable Update For FK Fields

1.5k Views Asked by At

I am using Django 1.9.

I have some models:

class MyOtherModel:
    my_other_prop = models.IntergerField()

class MyModel:
    some_prop = models.IntegerField()
    my_other_model = models.ForeignKey(MyOtherModel)

And my admin model is:

class MyModelAdmin(ModelAdmin):
    model = MyModel
    fields = ['some_prop', 'my_other_model']

Now this by default will give me the ability to set my_other_model, create my_other_model and update my_other_model on the form. What I want to do is disable editing(updating) my_other_model. I still want to be able to set it and still want to be able to create one from MyModelAdmin. Since MyOtherModel is not exposed via admin any other place the idea is that from the admin section point of view the model is immutable.

I've dug around the Django docs and have Googled quite a bit but am not finding a way to accomplish this. I don't want the field to be read-only because I want to be able to create them. I don't think I want to override get_readonly_fields() to return false if the object exists in this case because I would still want to be able to change which MyOtherModel MyModel has.. just not edit MyOtherModel itself.

Could anyone point me in the right direction here? Should I be using a different approach? Any advice would be appreciated, thanks much!

2

There are 2 best solutions below

0
On BEST ANSWER

You can override the get_form() method in the admin class to use a different form in the edit & create pages:

class ReadOnlyPkForm(ModelForm):
    class Meta:
        model = MyModel
        exclude = ('myothermodel',)



class MyModelAdmin(ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if obj: # Object intstance, so we're in edit page
            # Override form, to use custom form 
            kwargs['form'] = ReadOnlyPkForm
        return super(MyModelAdmin, self).get_form(request, obj, **kwargs)

The previous snippet would use the custom ReadOnlyPkForm form -- which excludes the field -- when you attempt to edit an instance. The standard form (i.e. all model fields) without exclusion would be used when you attempt to create a new instance. You could further tweak ReadOnlyPkForm through init if you wanted the field to appear as read-only (I just used exclude to make the sample easier).

Note admin classes also have change_view() and add_view() methods that you could also use to override the forms in edit / create pages , but in my experience they are for more complex modifications (e.g. the underyling template) not to mention these two methods can have quirky behavior due to caching issues.

2
On

If I understand your question correctly would this work?

Disable link to edit object in django's admin (display list only)?