Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add dynamic field to django admin model form

Tags:

python

django

I need to add the field with link to the model view on my site to the django admin view. When I add field name to the list_display and define method for rendering this url:

class SetAdmin(admin.ModelAdmin):
    list_display = ['many other fields', 'show_set_url']

    def show_set_url(self, obj):
            return '<a href="#">Set</a>' # render depends on other fields

It shows in Sets list in django admin, but not in model form. How can I fix this and add link to the Sets Form in django admin?

I've tried also to create custom form for this model:

from core.models import Set
from django import forms

class SetAdminForm(forms.Form):
    class Meta:
        model = Set

    def __init__(self, *args, **kwargs):
        super(SetAdminForm, self).__init__(*args, **kwargs)
        self.fields['foo'] = forms.IntegerField(label=u"Link")

But there is now visible effect in form.

like image 492
Paul Avatar asked Jun 16 '14 07:06

Paul


People also ask

How do you make a field non mandatory in Django admin?

The simplest way is by using the field option blank=True (docs.djangoproject.com/en/dev/ref/models/fields/#blank).

Can we customize Django admin panel?

We have a lot of tools in Django to customize it to our own needs and in this article, we'll learn how to customize the admin interface and add multiple features: Let's setup your project, add models into models.py and register your models.

What is Fieldsets in Django admin?

Set fieldsets to control the layout of admin “add” and “change” pages. fieldsets is a list of two-tuples, in which each two-tuple represents a <fieldset> on the admin form page. (A <fieldset> is a “section” of the form.)


2 Answers

You can accomplish what you're trying by overriding ModelAdmin but you also need to override ModelAdmin.get_fieldsets. This answer might help you out. The OP in the link has a similar problem as well.

Edit: If you don't want an editable field you can try overriding ModelAdmin.get_readonly_fields. Also check here for more attributes to override.

like image 129
Tamer Tas Avatar answered Oct 01 '22 17:10

Tamer Tas


You can create dynamic fields and fieldset using the form meta class. Sample code is given below. Add the loop logic as per you requirements.

class CustomAdminFormMetaClass(ModelFormMetaclass):
    """
    Metaclass for custom admin form with dynamic field
    """
    def __new__(cls, name, bases, attrs):
        for field in myloop: #add logic to get the fields
            attrs[field] = forms.CharField(max_length=30) #add logic to the form field
        return super(CustomAdminFormMetaClass, cls).__new__(cls, name, bases, attrs)


class CustomAdminForm(six.with_metaclass(CustomAdminFormMetaClass, forms.ModelForm)):
    """
    Custom admin form
    """

    class Meta:
        model = ModelName
        fields = "__all__" 


class CustomAdmin(admin.ModelAdmin):
    """
    Custom admin 
    """

    fieldsets = None
    form = CustomAdminForm

    def get_fieldsets(self, request, obj=None):
        """
        Different fieldset for the admin form
        """
        self.fieldsets = self.dynamic_fieldset(). #add logic to add the dynamic fieldset with fields
        return super(CustomAdmin, self).get_fieldsets(request, obj)

    def dynamic_fieldset(self):
        """
        get the dynamic field sets
        """
        fieldsets = []
        for group in get_field_set_groups: #logic to get the field set group
            fields = []
            for field in get_group_fields: #logic to get the group fields
                fields.append(field)

            fieldset_values = {"fields": tuple(fields), "classes": ['collapse']}
            fieldsets.append((group, fieldset_values))

        fieldsets = tuple(fieldsets)

        return fieldsets
like image 42
santhoshnsscoe Avatar answered Oct 01 '22 19:10

santhoshnsscoe