9

I am using wagtails' ModelAdmin module ( not the same as Django ModelAdmin) to add a custom Order model to the wagtail admin. This model has a foreign key to a custom Address model.

I would like to display the Address model as an inline (like in django's admin) in the InspectView (which I have enabled). Currently it displays the string representation.

jramm
  • 6,415
  • 4
  • 34
  • 73
  • Long time since this was asked but curious did you get this solved, this might be a good answer for future users. Alternatively it would be great if this question had a bit more info about your model structure for future answers to be given. Thanks – LB Ben Johnston Dec 07 '21 at 21:58

2 Answers2

2

Background

You have to create a class by inheriting ModelAdmin class and state the model associated with that ModelAdmin. This is ModelAdmin basics and you can find it in the documentation. Also Inspect View basics can be found in this documentation.

class OrderAdmin(ModelAdmin):
    model = Order
    inspect_view_enabled = True
    inspect_view_fields = (
        'id',
        'date',
    )

I have this model called Order and I need to display only id and date in the wagtail inspect view. Also I have an Address model with a one-to-one relation to the Order model. I need to show city from that Address in the inspect view.

Answer

But if just add new field like following, it will give an error as wagtail can't find a field called city in Order model.

inspect_view_fields = (
    'id',
    'date',
    'city',
)

How wagtail resolve fields

For every field in inspect_view_fields array, wagtail calls a method called get_dict_for_field to get the associated label and the value for that field. You can easily override this method. After overriding you should tell wagtail to used the overridden method. You can do so as follows.

class OrderInspectView(InspectView):
    def get_dict_for_field(self, field_name):    # Override to support custom fields
        # Do the implementation for custom fields
        return super().get_dict_for_field(field_name)

class OrderAdmin(ModelAdmin):
    model = Order
    inspect_view_enabled = True
    inspect_view_class = OrderInspectView    # Tell wagtail to use our class instead of the default class
    inspect_view_fields = (
        'id',
        'name',
        'city',    # Custom field
    )

What you need to do now is to get the Address associated with the Order and return it. You can get the current inspecting Order using self.instance.

def get_dict_for_field(self, field_name):
    if field_name == 'city':
        qs = Address.objects.filter(order=self.instance.id)
        value = str(qs[0].city) if len(qs) > 0 else '-'
        return {
            'label': 'City',
            'value': value,
        }
    return super().get_dict_for_field(field_name)
Ramesh-X
  • 4,853
  • 6
  • 46
  • 67
-1

I have not used the InspectView often but it represents the model as a renedered template without fielsd etc. So maybe you can define your own template and call a custom property from Order {{ value.bound_blocks.order.full_addres }} on it.

Hope this is of any use,

Robert

Robert
  • 261
  • 2
  • 11