Lets say I have two models and a form:
class Person(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
class Car(models.Model):
plate = models.CharField(max_length=255)
persons = models.ManyToManyField(Person)
class CarAddForm(forms.ModelForm):
plate = forms.CharField()
persons = forms.ModelMultipleChoiceField(queryset=Person.objects.all())
class Meta:
model = Car
fields = [
'plate',
'persons'
]
Is there a way to get ModelMultipleChoiceField queryset of people that are NOT associated with any car? In case of editing Car model object, the queryset should contain people that are NOT associated with any car PLUS people that are associated with the car being edited
PS: maybe there is a better way to achieve this?
You can make use of the limit_choices_to
--(Doc) argument of ManyToManyField
as
class Car(models.Model):
plate = models.CharField(max_length=255)
persons = models.ManyToManyField(
Person,
)
Alternatively, you can also alter the queryset
argument of ModelMultipleChoiceField
as
class CarAddForm(forms.ModelForm):
plate = forms.CharField()
persons = forms.ModelMultipleChoiceField(
)
class Meta:
model = Car
fields = [
'plate',
'persons'
]
You can specify a filter for the query:
from django.db import models
class CarAddForm(forms.ModelForm):
...
persons = forms.ModelMultipleChoiceField(
queryset=Person.objects\
.annotate(car_count=models.Count('cars'))\
.filter(car_count=0))
...
Another options is to override the forms __init__()
method. Maybe like this:
from django.db import models
class CarAddForm(forms.ModelForm):
...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['person'].queryset = self.fields['person'].queryset\
.annotate(car_count=models.Count('cars'))\
.filter(car_count=0))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.