获取Django中的外键关联对象

huangapple go评论88阅读模式
英文:

Get foreign key related objects in Django

问题

  1. 我有3个模型
  2. class Organization(models.Model):
  3. name = models.CharField(max_length=250, unique=True)
  4. def __str__(self):
  5. return self.name
  6. class AppealForm(models.Model):
  7. form_name = models.CharField(max_length=100)
  8. def __str__(self):
  9. return self.form_name
  10. class Appeal(models.Model):
  11. organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, blank=True, null=True)
  12. appeal_form = models.ForeignKey(AppealForm, on_delete=models.CASCADE, blank=True, null=True)
  13. appeal_number = models.CharField(max_length=100, blank=True, null=True)
  14. applicant_first_name = models.CharField(max_length=100, blank=True, null=True)
  15. applicant_second_name = models.CharField(max_length=100, blank=True, null=True)
  16. date = models.DateField(blank=True, null=True)
  17. appeal_body = models.TextField()
  18. 模型的对象
  19. **Organization**
  20. |#|name|
  21. |-|-|
  22. |1|苹果|
  23. |2|三星|
  24. |3|戴尔|
  25. **AppealForm**
  26. |#|form_name|
  27. |-|-|
  28. |1|书面|
  29. |2|口头|
  30. **Appeal**
  31. |#|organization|appeal_form|appeal_number|applicant_first_name|applicant_second_name|date|appeal_body|
  32. |-|-|-|-|-|-|-|-|
  33. |1|苹果|书面|abc1|奥利弗|杰克|06/22/2023|测试上诉正文文本|
  34. |2|苹果|口头|abc12|杰克|康纳|05/22/2023|测试上诉正文文本|
  35. |3|苹果|口头|abc123|哈利|卡勒姆|04/22/2023|测试上诉正文文本|
  36. |4|戴尔|书面|abc1234|查理|威廉|03/22/2023|测试上诉正文文本|
  37. |5|戴尔|口头|abc12345|乔治|里斯|02/22/2023|测试上诉正文文本|
  38. **我想从组织模型查询生成以下表格**
  39. | # | 组织 | 总上诉数量 | 书面上诉数量 | 口头上诉数量 |
  40. | - | --- |--- |--- |--- |
  41. | 1 | 苹果 | 3 | 1 | 2 |
  42. | 2 | 三星 | 0 | 0 | 0 |
  43. | 3 | 戴尔 | 2 | 1 | 1 |
  44. *查询将是什么样子*
  45. 提前感谢
  46. ==========================================
  47. **更新**
  48. *filters.py*
  49. ```python
  50. class AppealFilter(django_filters.FilterSet):
  51. appeal__date = django_filters.DateFromToRangeFilter(widget=django_filters.widgets.RangeWidget(attrs={'type': 'date'}))
  52. class Meta:
  53. model = Organization
  54. fields = ['appeal__date']
英文:

I have 3 models:

  1. class Organization(models.Model):
  2. name = models.CharField(max_length=250, unique=True)
  3. def __str__(self):
  4. return self.name
  5. class AppealForm(models.Model):
  6. form_name = models.CharField(max_length=100)
  7. def __str__(self):
  8. return self.report_form_name
  9. class Appeal(models.Model):
  10. organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, blank=True, null=True)
  11. appeal_form = models.ForeignKey(AppealForm, on_delete=models.CASCADE, blank=True, null=True)
  12. appeal_number = models.CharField(max_length=100, blank=True, null=True)
  13. applicant_first_name = models.CharField(max_length=100, blank=True, null=True)
  14. applicant_second_name = models.CharField(max_length=100, blank=True, null=True)
  15. date = models.DateField(blank=True, null=True)
  16. appeal_body = models.TextField()

Objects of models:

Organization

# name
1 Apple
2 Samsung
3 Dell

AppealForm

# form_name
1 Written
2 Oral

Appeal

# organization appeal_form appeal_number applicant_first_name applicant_second_name date appeal_body
1 Apple Written abc1 Oliver Jake 06/22/2023 Test appeal body text
2 Apple Oral abc12 Jack Connor 05/22/2023 Test appeal body text
3 Apple Oral abc123 Harry Callum 04/22/2023 Test appeal body text
4 Dell Written abc1234 Charlie William 03/22/2023 Test appeal body text
5 Dell Oral abc12345 George Reece 02/22/2023 Test appeal body text

I want to generate a table like this below querying from Organization model:

# Organization Total amount of appeals Written appeals amount Oral appeals amount
1 Apple 3 1 2
2 Samsung 0 0 0
3 Dell 2 1 1

How the query will look like?
Thanks in advance!

==========================================

UPDATED:

filters.py

  1. class AppealFilter(django_filters.FilterSet):
  2. appeal__date = django_filters.DateFromToRangeFilter(widget=django_filters.widgets.RangeWidget(attrs={'type': 'date'}))
  3. class Meta:
  4. model = Organization
  5. fields = ['appeal__date ']

答案1

得分: 2

你可以像这样在这里进行注释

  1. Organization.objects.annotate(total_appeals=Count('appeal'), written_appeals=Count('appeal', filter=Q(appeal__appeal_form__form_name="written")),
  2. oral_appeals=Count('appeal', filter=Q(appeal__appeal_form__form_name="Oral")))

在这里,我正在从组织反向查询 到申诉,然后附加每个组织的申诉计数。我正在使用注释过滤 来区分口头和书面申诉。

英文:

You can do annotation here like this:

  1. Organization.objects.annotate(total_appeals=Count('appeal'), written_appeals=Count('appeal', filter=Q(appeal__appeal_form__form_name="written")),
  2. oral_appeals=Count('appeal', filter=Q(appeal__appeal_form__form_name="Oral")))

Here I am reverse querying from Organization to Appeal and attaching the count of Appeals for each organization. I am using filter on annotation to separate Oral and Written appeals.

huangapple
  • 本文由 发表于 2023年6月22日 16:04:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76529750.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定