Django spanning relationships

2020-07-10 09:29发布

I've read the documentation but am still coming up with errors. I have Users placing Orders for Catalog objects. I'd like to create a query which returns all Users that have an Order containing a specific Catalog item.

Here are my models:

class Catalog(models.Model):
  name = models.CharField(max_length=100)
  price = models.IntegerField()

  def __unicode__(self):
      return self.name

class Annual(models.Model):
  catalog = models.OneToOneField(Catalog, blank=True, null=True, related_name='annual_products')
  year_id = models.IntegerField(max_length=4)
  start_date = models.CharField(max_length=10)
  end_date = models.CharField(max_length=10)
  date = models.DateTimeField(auto_now_add=True, blank=True)
  def __unicode__(self):
      return unicode(self.year_id)

class Order(models.Model):
  user = models.ForeignKey(User, related_name='who_ordered')
  select = models.ManyToManyField(Catalog, related_name='annuals_ordered', blank=True, null=True)

  def __unicode__(self):
      return unicode(self.user)

Here is the query I've been trying:

 Catalog.objects.filter(order__select__annual='2014')

2条回答
再贱就再见
2楼-- · 2020-07-10 09:32

If you need users, you should start with users. Also, you need to filter on a specific field in Annual, ie year_id.

User.objects.filter(order__select__annual__year_id=2014)
查看更多
手持菜刀,她持情操
3楼-- · 2020-07-10 09:38

If I got your question correctly then, your query is wrong. There is no attribute name order inside your Catalog model, then how can you use it for filtering ? Or I'm missing anything here ?

Directly using the related name references on the related fields, you can get the users by using -

# id is auto generated field or you can pass one annual_product object.
User.objects.filter(who_ordered__select__annual_products__id=1)

# OR
annual = Annual.objects.all()[0]
User.objects.filter(who_ordered__select__annual_products=annual)

The step by step how you can achieve the same :-

# where 1 is the id of an one object in Catalog model.
# You can pass Catalog object also to filter the users
Order.objects.filter(select__id=1)

# Here is the full query 
catalog = Catalog.objects.all()[0]
orders = Order.objects.filter(select=catalog)
users = [o.user for o in orders]  # This loop isn't necessary.

Now you have all orders specific to one Catalog, from this you can get the user object by using the user attribute in each order.

查看更多
登录 后发表回答