Django - Limit choices to something that depends on the instance

泪湿孤枕 提交于 2020-01-02 02:20:30

问题


I have some foos which are organized into categories. For each category, I want to be able to select a winner foo.

Hence I have models which look like this:

class Category(models.Model):
    name = models.CharField(max_length=30)
    # More fields...
    winner = models.ManyToManyField(
        'Foo',
        related_name='winner'
    )

class Foo(models.Model):
    name = models.CharField(max_length=30)
    # More fields...
    category = models.ForeignKey(
        Category,
        related_name='category'
    )

(The reason why winner is a ManyToManyField is that a single foo may belong to several categories, while in a single category there may be more than one winner due to ex-aequo.)

I want to impose the natural constraint that a foo can win in a category only if it belongs to that category. The most reasonable way to do so seems to use the limit_choices_to parameter, but it seems to me that it is not possible to limit the choices based on the current instance of the model.

I may be able to impose this constraint in a given form, but I would like to avoid this for two reasons:

  • the constraint naturally lives at the model level. It is a particular relation that should always hold between two related models
  • the choice of the winner will be made in the admin, and I would like to avoid having to customize the admin forms

Is there any way to impose this constraint in Django?


回答1:


There is no way to put constraint on M2M field on the models level (ie with limit_choices_to). However, you can do this in the form:

class MyForm(forms.ModelForm):
    class Meta:
        model = models.Category

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        if 'instance' in kwargs:
            my_category = kwargs['instance']
            self.fields['winner'].queryset = my_category.category.all()

Well, did you notice that?

my_category.category.all()

Probably what you want is:

class Foo(models.Model):
    name = models.CharField(max_length=30)
    # More fields...
    category = models.ForeignKey(
        Category,
        related_name='participants'
    )


来源:https://stackoverflow.com/questions/7672826/django-limit-choices-to-something-that-depends-on-the-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!