Menas
Menas

Reputation: 1269

How to hide field from admin change page but keep it in admin add page in Django

I have a data model in which some fields can only be set initially per each instance of the class, and once set, they should never change. The only way that can be allowed to change such an object should be by deleting it and creating a new one.

Pseudo code:

from django.db import models
from django.core.exceptions import ValidationError


class NetworkConnection(models.Model):
    description = models.CharField(max_length=1000)
    config = models.CharField(max_length=1000)
    connection_info = models.CharField(max_length=5000)
    def clean(self):
        from .methods import establish_connection
        self.connection_info = establish_connection(self.config)
        if not self.connection_info:
            raise ValidationError('Unable to connect')
    def delete(self):
        from .methods import close_connection
        close_connection(self.config)
        super(NetworkConnection, self).delete()

As in the above code, the user should initially input both the config and the description fields. Then Django verifies the config and establishes some sort of network connection based on such configurations and saves its information to another field called connection_info.

Now since each object of this class represents something that cannot be edited once created, I need to hind the config field from the admin page that edits the object, leaving only the description field; However, the config field still needs to be there when adding a new connection. How do I do this?

The following is an example of my last admin.py attempt:

from django.contrib import admin
from .models import NetworkConnection

class NetworkConnectionAdmin(admin.ModelAdmin):
    exclude = ('connection_info')
    def change_view(self, request, object_id, extra_context=None):       
        self.exclude = ('config')
        return super(NetworkConnection, self).change_view(request, object_id, extra_context)

admin.site.register(NetworkConnection, NetworkConnectionAdmin)

But unfortunately, it seems to hide the config field from the add page too. Not only the change page

Upvotes: 0

Views: 820

Answers (2)

Marco
Marco

Reputation: 2844

You can achieve that with a custom method directly in your NetworkConnectionAdmin class:

from django.contrib import admin
from .models import NetworkConnection

class NetworkConnectionAdmin(admin.ModelAdmin):
    exclude = ('connection_info')

    def get_readonly_fields(self, request, obj=None):
        if obj:
            return ["config", "description"]
        else:
            return []

admin.site.register(NetworkConnection, NetworkConnectionAdmin)

I got it from the Django Admin Cookbook.

Upvotes: 1

Menas
Menas

Reputation: 1269

Turns out this could be done using the ModelAdmin.get_from function but if anybody has a better answer, please share it

Solution using get_from would be:

admin.py

from django.contrib import admin
from .models import NetworkConnection

class NetworkConnectionAdmin(admin.ModelAdmin):
    exclude = ('connection_info')
    def get_form(self, request, obj=None, **kwargs):
        if obj:
            kwargs['exclude'] = ('config')
        return super(NetworkConnectionAdmin, self).get_form(request, obj, **kwargs)
admin.site.register(NetworkConnection, NetworkConnectionAdmin)

Upvotes: 0

Related Questions