Django ORM,parent 和 child 连接

Django ORM, parent and child connecting

Django ORM

大家好,

希望大家都好。

我有两个表要加入,但很难以特定方式加入。

我可以使用 SQL 轻松加入他们,但我更想使用 Django 来完成。

以下型号;

Child:

    class employee(models.Model):
    client = models.ForeignKey(client, on_delete=models.CASCADE)
    mySharePlan_ID = models.CharField(max_length=10, unique=True)
    payroll_ID = models.CharField(max_length=100)
    first_name = models.CharField(max_length=155,)
    middle_name = models.CharField(max_length=155,null=True, blank=True)
    last_name = models.CharField(max_length=155)
    TFN = models.IntegerField(null=True,blank=True)
    subsidary = models.CharField(max_length=155,null=True, blank=True)
    divison = models.CharField(max_length=155,null=True, blank=True)
    job_title = models.CharField(max_length=155,null=True, blank=True)
    tax_rate = models.FloatField(null=True,blank=True)
    hire_date = models.DateField(null=True,blank=True)
    terminiaton_date = models.DateField(null=True,blank=True)
    termination_reason = models.CharField(max_length=155, blank=True)
    rehire_date = models.DateField(null=True,blank=True)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.DO_NOTHING)
    class Meta:
        unique_together = ('client', 'payroll_ID',)

    def __str__(self):
        full_name = "Payroll ID: " + self.payroll_ID + ", " + self.first_name + " " + self.last_name
        return full_name

Parent:

    class offer_eligibility(models.Model): 
    offer = models.ForeignKey(offer,on_delete=models.CASCADE)
    employee = models.ForeignKey(employee,on_delete=models.CASCADE)
    amount_offered = models.PositiveBigIntegerField()
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.DO_NOTHING)

任何员工都可以有多个offer。

我正在尝试创建一个视图,该视图显示在所选报价中的员工列表以及他们是否有 amount_offered。

这需要我先通过报价过滤 offer_eligibility,我有这个查询集。 (注意:我意识到我不应该过滤这个)

我想将该查询集添加到员工查询集(由客户端过滤,很容易过滤),如果查询集中不存在员工,我希望 amount_offered 为 None/null。

目前我无法将 parent 数据加入到 child 数据中,我尝试了一些不同的方法,但在原始 SQL 中这是相当微不足道的,所以我以为我显然不明白什么。

已编辑:SQL 下面;

SELECT [staff_employee].[id]
      ,[mySharePlan_ID]
      ,[payroll_ID]
      ,[first_name]
      ,[last_name]
      ,[TFN]
      ,[subsidary]
      ,[divison]
      ,[job_title]
      ,[tax_rate]
      ,[hire_date]
      ,[terminiaton_date]
      ,[termination_reason]
      ,[rehire_date]
      ,[client_id]
      ,iif(offer_id != 3, 0, [amount_offered]) /* 3 is the offer PK */

  FROM [ESS_Database].[dbo].[staff_employee] left join [staff_offer_eligibility] on [staff_employee].id = employee_id

  where client_id = 1 

感觉很亲近

我只需要将值更改为 F('offer_eligibility__amount_offered') 但是当我这样做时出现错误。

"引发 FieldError('Cannot resolve expression type, unknown output_field') django.core.exceptions.FieldError: 无法解析表达式类型,未知 output_field"

qs = queryset.filter(client=context['selected_client'][1]).annotate(
                amount_offered=Case(
                When( offer_eligibility__offer = self.kwargs['pk'] 
                ,then=Value(0))
                ,default=None)).query

非常感谢任何帮助。

提前致谢, 汤姆

我明白了!经过一整天的努力。

感觉现在对Django的写法有了更深的理解SQL

过滤模型查询集

def get_queryset(self): #Filter queryset for client
        queryset = super(FilterView, self).get_queryset()
        context = selected_client(self.request)
        queryset = queryset.filter(client=context['selected_client'][1]).annotate(
                amount_offered=Case(
                When( offer_eligibility__offer = self.kwargs['pk'] 
                ,then=F('offer_eligibility__amount_offered'))
                ,default=None))
        return queryset 

我的 Django-tables2:

    class offer_eligibility_table(ExportMixin,tables.Table):
    client_name = tables.Column(accessor='client__client_name')
    mySharePlan_ID = tables.Column(accessor='mySharePlan_ID')
    payroll_ID = tables.Column(accessor='payroll_ID')
    first_name = tables.Column(accessor='first_name')
    middle_name = tables.Column(accessor='middle_name')
    last_name = tables.Column(accessor='last_name')
    hire_date = tables.Column(accessor='hire_date')
    amount_offered = tables.Column(accessor='amount_offered')

所以为了让您了解答案,我首先需要在客户端进行过滤,然后我需要向原始模型添加一列,这是我的 amount_offered 但我只想添加值,如果员工在报价中,因此我需要使用案例功能,如果您正在查看我的问题并需要类似的帮助,绝对建议阅读 conditional-expressions。

https://docs.djangoproject.com/en/4.0/ref/models/conditional-expressions/

所以我不得不更改它我最终用报价 ID 注释了一个列,如果它们为空或相同的报价 ID,然后过滤该报价 ID,如果我能弄清楚如何进行内部连接就好了. >.>