Взаимоотношения в Django между дочерней и родительской моделью

Я занят проектом, в котором у меня есть две модели, и я не уверен, как это сделать, поскольку я довольно новичок в программировании. Я хотел бы сделать шаблон, который

  • выводит все экземпляры первой модели

    .
  • и затем в том же шаблоне я хочу иметь все продажи, связанные с каждым из этих экземпляров, а также экземпляры с различными состояниями (например, если экземпляр первой модели связан с 2 продажами, которые имеют состояние "Подтверждено", то рядом с именем этого экземпляра должно быть написано 2)

    .
   class QAAgent(models.Model):
        user=models.OneToOneField(User,on_delete=models.SET_NULL,null=True)
        Qa_name = models.CharField(max_length=15)
            
        def __str__(self):
          return self.user.username
      
   States = (('Pending',"Pending"),("Confirmed","Confirmed"),("Requested","Requested),("Cancelled","Cancelled"),("Not interested","Not interested"))
   class Sale(models.Model):
          QA = models.ForeignKey(QAAgent,on_delete=models.SET_NULL,blank=True,
          null=True,related_name="sale")
          State = models.CharField(choices=States,default="Pending",max_length=15)
          Date_created = models.DateTimeField(auto_now_add=True)
          Date_edited = models.DateTimeField(auto_now=True)
          
          def__str__(self):
              return self.client_name + " " + self.client_surname 

Чтобы перечислить все записи первой модели, включая связанные с ней элементы, вы можете сделать следующее. Только не забудьте передать правильный набор запросов в контекст представления.

{% for entry in qa_agent %}
    {{ entry.Qa_name}}
    {{ entry.user.name }}
    {% for sale in entry.sale.all %}
        {{sale.category.state }} 
    {% endfor %}
{% endfor %}

Для второго запроса просто создайте метод в классе модели, который будет фильтровать нужный статус. Здесь я назвал его get_confirmed.

class QAAgent(models.Model):
    user = models.OneToOneField(User, on_delete=models.SET_NULL, null=True)
    qa_name = models.CharField(max_length=15)  # You had Qa_name before

    def get_confirmed(self):
        return self.qa_sale.filter(state="Pending") # just write a method like this one for each of the other statuses.

    def __str__(self):
        return self.user.username

А затем измените код вашего шаблона так, чтобы он использовал этот метод для отображения подтвержденных.

{% for entry in qa_agent %}
    {{ entry.Qa_name}}
    {{ entry.user.name }}
    {{ entry.get_confirmed.count }} # <-- like this
{% endfor %}

Небольшое примечание о стилизации кода python. Для переменных и имен функций используйте snake_case. Для классов используйте CamelCase. Поэтому для свойств модели лучше всего использовать только строчные буквы и разделять слова подчеркиванием. Для классов начинайте с заглавной буквы и разделяйте слова, используя заглавную букву для первой буквы нового слова. Вот как это должно выглядеть:

states = (
    ("Pending", "Pending"),
    ("Confirmed", "Confirmed"),
    ("Requested", "Requested"),
    ("Cancelled", "Cancelled"),
    ("Not interested", "Not interested"),
)

class Sale(models.Model):
    qa = models.ForeignKey(QAAgent, on_delete=models.SET_NULL, blank=True, null=True, related_name="qa_sale")
    state = models.CharField(choices=States, default="Pending", max_length=15)
    date_created = models.DateTimeField(auto_now_add=True)
    date_edited = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.client_name} {self.client_surname}" # If you concatenate strings use an fstring like I did here. It's more readable
Вернуться на верх