Felipe Dourado
Felipe Dourado

Reputation: 441

Django: display only the items available in an admin form | OneToOneField

I have 4 class models:

class Category(models.Model):
    name = models.CharField(max_length=200)

    def __str__(self):
        return self.name

class Buyer(models.Model):
    name = models.CharField(max_length=200, blank=True)
    description = models.CharField(max_length=200, blank=True)

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

class Buy(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    buy_price = models.DecimalField(max_digits=6, decimal_places=2)

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

class Sell(models.Model):
    item = models.OneToOneField(Buy, related_name='sell', on_delete=models.CASCADE)
    total_paid = models.DecimalField(max_digits=6, decimal_places=2)
    buyer = models.ForeignKey(Buyer, related_name='sell', on_delete=models.CASCADE)

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

In the form admin page, the item field (Sell class) shows all the items available in the Buy model, regardless they've already been chosen before. As this items belongs to OneToOneField it doesn't make sense to display them because they can't be added anymore.

Example:

Buy
id category buy_price
6  ring     20
7  ring     30  
8  ring     40

Sell
item total_paid buyer
6    80         Ana
7    100        Kate

What the admin form is displaying:
enter image description here

What I was expecting is to be shown only the item 8, the one who has not been added before. In this way, how can I display only the items, in the admin form, that hasn't been chosen yet?

Thank you!

Upvotes: 0

Views: 276

Answers (1)

Felipe Dourado
Felipe Dourado

Reputation: 441

After some hours studying I think I figure out how to solve this issue:

class SellAdmin(admin.ModelAdmin):

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "item":
            kwargs["queryset"] = Buy.objects.filter(sell__buyer__isnull=True)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

Upvotes: 1

Related Questions