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:
Is there any way to impose this constraint in Django?
Update: ForeignKey. limit_choices_to allows to specify either a constant, a callable or a Q object to restrict the allowable choices for the key.
In Python, the @property decorator allows you to call custom model methods as if they were normal model attributes. For example, if you have the following greeting method, class Person: def __init__(self, first_name): self.
The two main concepts of OOP are classes and objects: Class: Class is basically a blueprint or a template for creating objects. Object: Collection of arguments and methods which can be performed on those data. An object is nothing but an instance of the class.
Choices limits the input from the user to the particular values specified in models.py . If choices are given, they're enforced by model validation and the default form widget will be a select box with these choices instead of the standard text field.
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'
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With