根据配置文件字段将三个模型关联在一起

时间:2018-09-03 20:14:32

标签: python django django-models django-select-related

我希望能够将我的用户模型,个人资料模型和单独的模型关联在一起。我当前的模型结构如下:

class Profile(models.Model):
    COORDINATOR = 1
    LEADER = 2
    ADMIN = 3
    ROLE_CHOICES = (
        (COORDINATOR, 'Coordinator'),
        (LEADER, 'Leader'),
        (ADMIN, 'Admin'),
    )
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    team = models.ForeignKey(Team, on_delete=models.PROTECT,null=True)
    role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
    agent_code = models.CharField(max_length=15, null=True, blank=True)

class DailyReports(models.Model):
    agent_code = models.CharField(max_length=15, blank=True, null=True)
    product = models.CharField(max_length=15)
    num_free = models.IntegerField(blank=True, null=True)
    apps_submitted = models.IntegerField(blank=True, null=True)
    apps_activated = models.IntegerField(blank=True, null=True)
    prem_submitted = models.DecimalField(max_digits=20, decimal_places=2,blank=True, null=True)
    date = models.DateField(auto_now=False,auto_now_add=False,null=True,blank=True)

我可以关联ProfileUser,但是我试图将ProfileDailyReports上的agent_code关联,然后与{{ 1}}模型。

因此,如下所示:

User

我得到预期的输出:

    test_query = DailyReports.objects.filter(product__in=['LT15', 'LT121']) \
            .values('agent_code') \
            .annotate(premium=Sum('prem_submitted')) \
            .order_by('-premium') \

但是我也想基于{'agent_code': 'ABC123', 'premium': Decimal('50015.87')} {'agent_code': 'DEF456', 'premium': Decimal('44818.20')} {'agent_code': 'GHI789', 'premium': Decimal('35322.35')} ... Profile获取信息,然后基于agent_code与{ {1}}和User,这样我的输出看起来像:

agent_code

1 个答案:

答案 0 :(得分:1)

如果一个配置文件将链接到多个DailyReports,则最佳设置必须是

class Profile(models.Model):
    COORDINATOR = 1
    LEADER = 2
    ADMIN = 3
    ROLE_CHOICES = (
        (COORDINATOR, 'Coordinator'),
        (LEADER, 'Leader'),
        (ADMIN, 'Admin'),
    )
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    team = models.ForeignKey(Team, on_delete=models.PROTECT,null=True)
    role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
    # agent_code = models.CharField(max_length=15, null=True, blank=True) # <-- Remove the agent code from the profile model.

DailyReports与配置文件具有多对一关系。

class DailyReports(models.Model):
    profile = models.ForeignKey('Profile', related_name='daily_reports')
    agent_code = models.CharField(max_length=15, blank=True, null=True)
    product = models.CharField(max_length=15)
    num_free = models.IntegerField(blank=True, null=True)
    apps_submitted = models.IntegerField(blank=True, null=True)
    apps_activated = models.IntegerField(blank=True, null=True)
    prem_submitted = models.DecimalField(max_digits=20, decimal_places=2,blank=True, null=True)
    date = models.DateField(auto_now=False,auto_now_add=False,null=True,blank=True)

获取个人资料的DailyReports列表

profile = Profile.objects.prefetch_related('daily_reports').first()

profile.daily_reports.all()

要通过配置文件报告进行查询

qs = (
    profile.daily_reports.filter(product__in=['LT15', 'LT121'])
        .annotate(premium=Sum('prem_submitted'))
        .values_list('agent_code', 'premium', 'profile__first_name', 'profile__last_name', 'profile__user_id', 'profile__role', named=True)
        .order_by('-premium')
)

results = [
    {
       'agent_code': report.agent_code,
       'premium': report.premium
       'first_name': report.profile__first_name,
       'last_name': report.profile__last_name,
       'user_id': report.profile__user_id,
       'role': report.profile__role
    } for report in qs
]

## {'agent_code': 'ABC123', 'premium': Decimal('479872.55'), ...}