Формы Django: как отображать в выпадающем списке только объекты, связанные с пользователем
Я ветеринарная клиника, с классом Pet и классом Records. У каждого питомца может быть много записей, то есть каждый раз, когда он посещает больницу, он получает новую запись.
На данный момент в моей форме отображаются все животные, которые когда-либо были связаны с моим приложением (см. ).
Я хочу, чтобы появлялись только зарегистрированные домашние животные пользователя (зачем Бобу приносить кошку незнакомца к ветеринару?)
Просмотр, чтобы добавить запись:
@login_required(login_url="/accounts/login/")
def record_create(request):
#this line retrieves Pets only belonging to the user logged in
pets = Pet.objects.filter(author=request.user)
if request.method == 'POST':
form = forms.CreateRecord(request.POST, request.FILES)
print(form)
if form.is_valid():
instance = form.save(commit=False)
instance.author = request.user
instance.save()
return redirect('records')
else:
form = forms.CreateRecord()
return render(request, 'records/record_create.html', {'form': form,})
forms.py
class CreateRecord(forms.ModelForm):
class Meta:
model = models.Record
fields = ['feedID', 'amountLeftOver', 'amountDispensed', 'additionalInfo', 'selectPet']
models.py
class Pet(models.Model):
petName = models.CharField(max_length=100, default='My Pet')
petImage = models.ImageField(default='default.png', blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, default=None)
def __str__(self):
return self.petName
class Record(models.Model):
feedID = models.AutoField(primary_key=True)
dateTime = models.DateTimeField(auto_now_add=True)
amountLeftOver = models.IntegerField(default='0')
amountDispensed = models.IntegerField(default='0')
additionalInfo = models.TextField(default=" ")
selectPet = models.ForeignKey(Pet, on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE, default=None)
Как мне получить выпадающий список selectPet, чтобы показать только зарегистрированных домашних животных Боба?
Спасибо за ваше время!
2 ответа
Вы можете переопределить __init__()
метод вашей формы для передачи дополнительных аргументов, в этом случае вы можете передать пользовательский экземпляр и установить набор запросов для выпадающего виджета.
(Не уверен, как вы связали модель Pet с моделью User, в примере ниже предполагается, что у вас есть внешний ключ)
class CreateRecord(forms.ModelForm):
class Meta:
model = models.record
fields = ['feedID', 'amountLeftOver', 'amountDispensed', 'additionalInfo', 'selectPet']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
user = self.kwargs.get('user')
if user:
self.fields['selectPet'].queryset = user.pet_set.all()
Другой способ решить эту проблему
Просмотр для добавления записи:
@login_required(login_url="/accounts/login/")
def record_create(request):
#this line retrieves Pets only belonging to the user logged in
pets = Pet.objects.filter(author=request.user)
if request.method == 'POST':
form = forms.CreateRecord(request.POST, request.FILES)
print(form)
if form.is_valid():
instance = form.save(commit=False)
instance.author = request.user
instance.save()
return redirect('records')
else:
form = forms.CreateRecord()
form.fields["category"].queryset=Record.objects.filter(user=request.user)
return render(request, 'records/record_create.html', {'form': form,})