获取Django中的外键关联对象

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

Get foreign key related objects in Django

问题

我有3个模型

class Organization(models.Model):
    name = models.CharField(max_length=250, unique=True)

    def __str__(self):
        return self.name 

class AppealForm(models.Model):
    form_name = models.CharField(max_length=100)

    def __str__(self):
        return self.form_name

class Appeal(models.Model):
    organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, blank=True, null=True)
    appeal_form = models.ForeignKey(AppealForm, on_delete=models.CASCADE, blank=True, null=True)
    appeal_number = models.CharField(max_length=100, blank=True, null=True)
    applicant_first_name = models.CharField(max_length=100, blank=True, null=True)
    applicant_second_name = models.CharField(max_length=100, blank=True, null=True)
    date = models.DateField(blank=True, null=True)
    appeal_body = models.TextField()

模型的对象

**Organization**
|#|name|
|-|-|
|1|苹果|
|2|三星|
|3|戴尔|

**AppealForm**
|#|form_name|
|-|-|
|1|书面|
|2|口头|

**Appeal**
|#|organization|appeal_form|appeal_number|applicant_first_name|applicant_second_name|date|appeal_body|
|-|-|-|-|-|-|-|-|
|1|苹果|书面|abc1|奥利弗|杰克|06/22/2023|测试上诉正文文本|
|2|苹果|口头|abc12|杰克|康纳|05/22/2023|测试上诉正文文本|
|3|苹果|口头|abc123|哈利|卡勒姆|04/22/2023|测试上诉正文文本|
|4|戴尔|书面|abc1234|查理|威廉|03/22/2023|测试上诉正文文本|
|5|戴尔|口头|abc12345|乔治|里斯|02/22/2023|测试上诉正文文本|

**我想从组织模型查询生成以下表格**
| # | 组织 | 总上诉数量 | 书面上诉数量 | 口头上诉数量 |
| - | --- |--- |--- |--- |
| 1 | 苹果 | 3 | 1 | 2 |
| 2 | 三星 | 0 | 0 | 0 |
| 3 | 戴尔 | 2 | 1 | 1 |

*查询将是什么样子*
提前感谢

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

**更新**

*filters.py*

```python
class AppealFilter(django_filters.FilterSet):
    appeal__date = django_filters.DateFromToRangeFilter(widget=django_filters.widgets.RangeWidget(attrs={'type': 'date'}))
    class Meta:
        model = Organization
        fields = ['appeal__date']
英文:

I have 3 models:

class Organization(models.Model):
name = models.CharField(max_length=250, unique=True)
def __str__(self):
return self.name 
class AppealForm(models.Model):
form_name = models.CharField(max_length=100)
def __str__(self):
return self.report_form_name
class Appeal(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, blank=True, null=True)
appeal_form = models.ForeignKey(AppealForm, on_delete=models.CASCADE, blank=True, null=True)
appeal_number = models.CharField(max_length=100, blank=True, null=True)
applicant_first_name = models.CharField(max_length=100, blank=True, null=True)
applicant_second_name = models.CharField(max_length=100, blank=True, null=True)
date = models.DateField(blank=True, null=True)
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

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

答案1

得分: 2

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

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

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

英文:

You can do annotation here like this:

Organization.objects.annotate(total_appeals=Count('appeal'), written_appeals=Count('appeal', filter=Q(appeal__appeal_form__form_name="written")),
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:

确定