5 votes

Limiter/filtrer les choix de clés étrangères dans Django Admin

Pensez à une application où les gens peuvent participer à un concours.

Tengo un Contest y ContestProblem Modèle prêt. Je veux avoir les caractéristiques suivantes pour le concours :

  1. Un concours peut présenter de nombreux problèmes
  2. Un problème ne peut apparaître dans plus d'un concours.

Dans mon models.py Je l'ai fait :

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)

Dans mon admin.py, j'ai :

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

class ContestAdmin(admin.ModelAdmin):

    inlines = [
        ContestProblemInline,
    ]

Voici à quoi ressemble mon formulaire d'administration : enter image description here

J'utilise Django Admin pour ajouter des problèmes à un concours. Le problème est que dans la liste déroulante des problèmes, j'obtiens tous les problèmes de la liste. ContestProblem mais je veux le limiter à ceux ContestProblem qui n'apparaît dans aucun autre concours.

Toute astuce, tout conseil ou toute référence permettant d'obtenir les résultats souhaités sera vivement apprécié.

4voto

Exprator Points 17661
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)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X