Is there a way to filter a model form based on a boolean value of the related model?

Viewed 38

i have three models in my Django project. Donor , Patient and Donation This a a blood donation web app i am trying to make.

Here is Donation model:

class Donation(models.Model):
    donor = models.ForeignKey(Donor, on_delete=models.CASCADE)
    patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
    donation_date = models.DateTimeField(auto_now=True)
    amount = models.DecimalField(max_digits=5, decimal_places=2)


    class Meta:
        ordering = ['-donation_date']

Here is the Patient model:

class Patient(models.Model):
    BLOOD_GROUPS = [
        ('O+', 'O+'),
        ('O-', 'O-'),
        ('A+', 'A+'),
        ('A-', 'A-'),
        ('B+', 'B+'),
        ('B-', 'B-'),
        ('AB+', 'AB+'),
        ('AB-', 'AB-'),
    ]
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=30)
    id_card = models.CharField(max_length=7)
    phone_number = models.CharField(max_length=7)
    blood_group = models.CharField(
        max_length=20, choices=BLOOD_GROUPS, default='O+')

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

    class Meta:
        ordering = ['first_name']

Here is the Donor model:

class Donor(models.Model):
    BLOOD_GROUPS = [
        ('O+', 'O+'),
        ('O-', 'O-'),
        ('A+', 'A+'),
        ('A-', 'A-'),
        ('B+', 'B+'),
        ('B-', 'B-'),
        ('AB+', 'AB+'),
        ('AB-', 'AB-'),
    ]
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    id_card = models.CharField(max_length=7)
    phone_number = models.CharField(max_length=7)
    blood_group = models.CharField(
        max_length=20, choices=BLOOD_GROUPS, default='O_Positive')
    availability = models.BooleanField(default=True)

    def __str__(self):
        return f"{self.last_name} - ({self.id_card})"

Okay so as you can see there is a boolean field in Donor model. Every time a donor donates blood, availability becomes false. Then when what i want to happen is to show only the donors with True availability state when i render the DonationForm when entering a new donation record. see demo of this donation form Suppose say Mclean from this donated and his availability becomes False. Next time when entering a new donation He should not show up. This is what i want to achieve. Can anyone help?

Here is the view for adding a new donation.

def new_donation(request):
if request.method == 'POST':
    form = DonationForm(request.POST or None)
    print(request.POST['donor'])
    if form.is_valid():
        donor = Donor.objects.get(id=request.POST['donor'])
        print(donor)
        donor.availability = False
        donor.save()
        form.save()
        return render(request, 'new_donation.html', {'form': form})
form = DonationForm()
return render(request, 'new_donation.html', {'form': form})

here is DonationForm:

class DonationForm(forms.ModelForm):
    class Meta:
        model = Donation
        fields = ['donor', 'patient', 'amount']
1 Answers

Add filtered queryset for donor form field

class DonationForm(forms.ModelForm):
    donor = forms.ModelChoiceField(queryset= Donor.objects.filter(availability=True)
    class Meta:
        model = Donation
        fields = ['donor', 'patient', 'amount']
Related