Search code examples
wagtailwagtail-admin

Wagtail: How to filter FieldPanel dynamically for ForeignKey values?


I have this Page with a ForeignKey districtobject:

class DistrictPage(Page):

    districtobject = models.ForeignKey(DistrictTranslated, on_delete=models.SET_NULL, null=True, blank=True)
    streamfield  = StreamField(BasicStreamBlock, null=True, blank=True, use_json_field=True)

    content_panels = Page.content_panels + [
        #InfoPanel(),
        FieldPanel('districtobject', classname="full"),
        FieldPanel('streamfield'),

    ]

In the wagtail admin interface the dropdown menu have to much values for districtobject. I want to implement a dynamic filter, which shows only a few entries based on the parent Page object.

How/where can I implement my own queryset for this dropdown?


Solution

  • I found the following solution:

    class DistrictPageForm(WagtailAdminPageForm):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            if self.instance and self.instance.get_parent():
                parent_page = self.instance.get_parent().specific
            else:
                parent_page = kwargs.get('parent_page', None)
    
            if parent_page:
                self.fields['districtobject'].queryset = DistrictTranslated.objects.filter(city_id=parent_page.cityobject.id)
    
    class DistrictPage(Page, CityVariables):
    
        districtobject = models.ForeignKey(DistrictTranslated, on_delete=models.SET_NULL, null=True, blank=True)
        streamfield  = StreamField(BasicStreamBlock, null=True, blank=True, use_json_field=True)
    
        content_panels = Page.content_panels + [
            FieldPanel('districtobject', classname="full"),
            FieldPanel('streamfield'),
        ]
    

    This works fine for viewing, creating, editing and deleting in my case. Not sure if this is the best practice doing this.