[Django]-Many to Many Exclude on Multiple Objects

2👍

Suggest you use customer.saved_deals to get the list of deal ids to exclude (use values_list to quickly convert to a flat list).

This should save you excluding by a field in a joined table.

deals = Deals.exclude( id__in=customer.saved_deals.values_list('id', flat=True) )

0👍

You’d want to change this:

deals = Deal.objects.exclude(customer.saved_deals).all()

To something like this:

deals = Deal.objects.exclude(customer__id__in=[1,2,etc..]).all()

Basically, customer is the many-to-many foreign key, so you can’t use it directly with an exclude.

0👍

Deals saved and deals dismissed are two fields describing almost same thing. There is also a risk too much columns may be used in database if these two field are allowed to store Null values. It’s worth to consider remove dismissed_deals at all, and use saved_deal only with True or False statement.

Another thing to think about is move saved_deals out of CustomerProfile class to Deals class. Saved_deals are about Deals so it can prefer to live in Deals class.

class Deal(models.Model):
    saved = models.BooleandField()
    ...

A real deal would have been made by one customer / buyer rather then few. A real customer can have milions of deals, so relating deals to customer would be good way.

class Deal(models.Model):
    saved = models.BooleanField()
    customer = models.ForeignKey(CustomerProfile)
    ....

What I want to do is retrieve deals for a customer, but I don’t want to include deals that they have dismissed.

deals_for_customer = Deals.objects.all().filter(customer__name = "John")

There is double underscore between customer and name (customer__name), which let to filter model_name (customer is related to CustomerProfile which is model name) and name of field in that model (assuming CutomerProfile class has name attribute)

deals_saved = deals_for_customer.filter(saved = True)

That’s it. I hope I could help. Let me know if not.

Leave a comment