Search code examples
djangodjango-modelsdjango-admin

Django Admin formfield_for_foreignkey for manytomany


My Model (simpliefied)

we have tours:

class Tour(models.Model):
    name = models.CharField(max_length=100)
    strecke = models.ManyToManyField(Strecke, through="Streckenreihenfolge")

A tour has sections:

class Strecke(models.Model):
    name = models.CharField(max_length=100)
    auftrag = models.ForeignKey("Auftrag", on_delete=models.CASCADE, null=True, blank=True)

And the sections are put in order

class Streckenreihenfolge(models.Model):
    strecke = models.ForeignKey(Strecke, on_delete=models.CASCADE)
    tour = models.ForeignKey("Tour", on_delete=models.CASCADE)
    reihenfolge = models.IntegerField()

In my admin, I want to give some restrictions on which sections (Strecke) to show. I thought about using formfield_for_foreignkey. It gets called, but it doesn't have any impact on the options to select from:

@admin.register(Tour)
class TourAdmin(admin.ModelAdmin):

    class StreckenreihenfolgeAdminInline(admin.TabularInline):
        model = Streckenreihenfolge
        autocomplete_fields = ["strecke"]
        ordering = ["reihenfolge"]
        extra = 0

        def formfield_for_foreignkey(self, db_field, request, **kwargs):
            print(db_field.name)
            if db_field.name == 'strecke':
                kwargs['queryset'] = Strecke.objects.filter(auftrag_id__exact=8)
            return super().formfield_for_foreignkey(db_field, request, **kwargs)
    

inlines = [StreckenreihenfolgeAdminInline, ]

Does formfield_for_foreignkey not work for manytomanyfields?

Update Found some more infos here: Django Admin - Filter ManyToManyField with through model Apparently formfield_for_manytomany doesn't work for inline forms.

I have then tried to use get_queryset(), which reduced the queryset, but somehow the autocomplete values are still unfiltered.

Maybe this image here is illustrating more what I'm try to achieve: enter image description here


Solution

  • Finally found the answer here: https://forum.djangoproject.com/t/django-admin-autocomplete-field-search-customization/7455/5

    Which results in the following code:

    @admin.register(Strecke)
    class StreckeAdmin(admin.ModelAdmin):
        search_fields = ["name"]
    
        def get_search_results(self, request, queryset, search_term):
            print("get serach results")
            queryset = queryset.filter(auftrag_id__exact=8)
            qs = super().get_search_results(request, queryset, search_term)
            print(qs)
            return qs