Взаимоотношения в 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