Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit/Filter Foreign Key Choices in Django Admin

Consider an app where people can participate in a contest.

I have a Contest and ContestProblem Model ready. I want to have following features for the contest:

  1. A contest can have many problems
  2. A problem can not appear in more than one contest

In my models.py, I have:

class ProblemsInContest(CreateUpdateDateModel):
    contest = models.ForeignKey(Contest)
    problem = models.ForeignKey(ContestProblem)

    class Meta:
        verbose_name = "Problem in Contest"
        verbose_name_plural = "Problems in Contest"

    def __str__(self):
        return "{problem}".format(problem=self.problem)

In my admin.py, I have:

class ContestProblemInline(admin.TabularInline):
    model = ProblemsInContest
    extra = 1


class ContestAdmin(admin.ModelAdmin):

    inlines = [
        ContestProblemInline,
    ]

This is how my Admin Form look: enter image description here

I am using Django Admin to add problems to a contest. The problem being the fact that in the Problem dropdown, it shows me all the ContestProblem but I want to limit it to only those ContestProblem which does not appear in any other contest.

Any hints or advice or references to achieve the desired results will be highly appreciated.

like image 469
inquilabee Avatar asked Mar 21 '18 08:03

inquilabee


1 Answers

class ContestProblemInline(admin.TabularInline):

    model = ProblemsInContest

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):

        field = super(RoomInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

        if db_field.name == 'your_field_name':
            if request._obj_ is not None:
                field.queryset = field.queryset.filter(your_field_name = request._obj_)  
            else:
                field.queryset = field.queryset.none()

        return field



class ContestAdmin(admin.ModelAdmin):

    inlines = (ContestProblemInline,)

    def get_form(self, request, obj=None, **kwargs):
        # just save obj reference for future processing in Inline
        request._obj_ = obj
        return super(ContestAdmin, self).get_form(request, obj, **kwargs)
like image 152
Exprator Avatar answered Sep 28 '22 05:09

Exprator