0

I am a vet hospital, with class Pet and class Records. Each pet can have many records, i.e. everytime it visits the hospital it gets a new record.

At the moment, my form shows all the pets ever associated with my app (please view https://i.stack.imgur.com/8j7V8.png).

I want only the user's registered pets to appear (why would Bob be bringing a stranger's cat to the vet?)

View to add a record:

@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)

How do I get the selectPet dropdown to show only Bob's registered pets?

Thanks for your time!

Ally Alfie
  • 131
  • 11

2 Answers2

0

You can override the __init__() method of your form to pass in extra arguments, in this case, you can pass in a user instance, and set the queryset for the dropdown widget.

(Not sure about how you have related the Pet model to the User model, the example below assumes you have a foreign key)

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()
RHSmith159
  • 1,823
  • 9
  • 16
  • 2
    Be careful about changing the signature of the form's init method; it can cause problems if the view is not correctly updated everywhere to send in the user. Rather, get user from the `kwargs` dict. – Daniel Roseman Nov 26 '18 at 10:04
0

Another way to resolve this problem

View to add a record:

@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,})
lord king
  • 38
  • 1
  • 4