Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I call a model method in django ModelAdmin fieldsets?

I want to display an embedded map on an admin form when data already exists in the db. I have the following code:

models.py

class Address(models.Model):
    address = models.CharField()

    def address_2_html(self):
        if self.address:
            # Return html for an embedded map using the entered address.
            return embedded_map_html
        else:
            return ''
    address_2_html.allow_tags = True

admin.py

class AddressAdmin(admin.ModelAdmin):
    fieldsets = [(label, {'fields': ['address','address_2_html']}),]

This doesn't work. I get an error:

'AddressAdmin.fieldsets[1][1]['fields']' refers to field 'address_2_html' that is missing from the form.

Another thing I tried was using the 'description' option for 'fieldsets', however, 'address_2_html' is not accessible within the scope of AddressAdmin. I did succeed at embedding a static map using 'description' which was cool but not cool enough.

like image 537
nu everest Avatar asked Feb 08 '13 17:02

nu everest


People also ask

What is __ str __ in Django?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model.

What is Fieldsets in Django admin?

It's just a way for you to be able to group the fields on a Model Admin Page. Just implement the example in the documentation and it should become apparent for you.

How do I create an instance of a Django model?

To create a new instance of a model, instantiate it like any other Python class: class Model (**kwargs) The keyword arguments are the names of the fields you've defined on your model. Note that instantiating a model in no way touches your database; for that, you need to save() .

How do I override a save in Django?

save() method from its parent class is to be overridden so we use super keyword. slugify is a function that converts any string into a slug. so we are converting the title to form a slug basically.


2 Answers

Like that (from memory):

class AddressAdmin(admin.ModelAdmin):
    fieldsets = [(label, {'fields': ['address','address_2_html']}),]
    readonly_fields = ['address_2_html']

    def address_2_html(self, obj):
        return obj.address_2_html()
    address_2_html.allow_tags = True
    address_2_html.short_description = 'Address display'
like image 101
Etienne Avatar answered Sep 17 '22 20:09

Etienne


Problem solved by overriding get_fieldsets() since the get_fieldsets() method allows access to the model object Address.

def get_fieldsets(self, request, obj=None):
    fs = [
        (self.label,  {'fields': ['address',]}),
        ('Map', {'fields': [], # required by django admin
                'description':obj.address_2_html(),
         }),
    ]
    return fs
like image 26
nu everest Avatar answered Sep 21 '22 20:09

nu everest