Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.4k views
in Technique[技术] by (71.8m points)

django - Query ManyToMany models to return number of instance of A that are linked to B and reverse?

EDIT 22/01/2021

Thanks for advices in models naming.

Here is diagram of my database: https://dbdiagram.io/d/5fd0815c9a6c525a03ba5f6f?

As you can see in this diagram, I have simplyed as Customers_Orders is in fact a ternary relationship with models comments. I decided to use an 'declared' throught models for this ternary relationship

Do I realy need to add a ManyToMany fields in Orders? I have a look at Django's doc example with person, group and membership (https://docs.djangoproject.com/fr/3.1/topics/db/models/) and a manytomany fiels is added only in Group model, not in Person model


I have 2 models (Customers and Orders) with a declared throught models (Customers_Orders) to manage manytomany relationship.

But I did'nt understand how to query to have :

  • for one Customer, all its orders: How many orders were made by each customer
  • for one Order, all its customers: How many customers were associated for each order

I have understood, I should do: c = Customers.objects.get(customer_id=1) c.CustomersOrders.all() but it failled AttributeError: 'Customers' object has no attribute 'CustomersOrdersComments'

class Customers(SafeDeleteModel):

    customer_id = models.AutoField("Customer id", primary_key = True)
    orders = models.ManyToManyField(Orders, through = Customers_Orders, related_name = "CustomersOrders") 
    created_at = models.DateTimeField("Date created", auto_now_add = True)

class Orders(SafeDeleteModel):
    
    order_id = models.AutoField("Order id", primary_key = True)
    created_at = models.DateTimeField("Date created", auto_now_add = True)

class Customers_Orders(SafeDeleteModel):

    order = models.ForeignKey("Orders", on_delete = models.CASCADE)
    customer = models.ForeignKey("Customers", on_delete = models.CASCADE)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can do this - Given these models:

class Customer(models.Model):
    name = models.CharField(max_length=30, default=None, blank=True, null=True)
    orders = models.ManyToManyField("Order", through="CustomerOrder", related_name="orders") 
    created_at = models.DateTimeField(auto_now_add=True)

class Order(models.Model):
    created_at = models.DateTimeField(auto_now_add = True)
    customers = models.ManyToManyField(Customer, through="CustomerOrder", related_name="customers") 

class CustomerOrder(models.Model):
    order = models.ForeignKey("Order", on_delete = models.CASCADE)
    customer = models.ForeignKey("Customer", on_delete = models.CASCADE)
customer = Customer.objects.first()

# Get count of their orders
customer_orders_count = customer.orders.all().count()

order = Order.objects.first()

# Get count of order's customers
order_customers_count = order.customers.all().count()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...