【问题标题】:Django ORM, parent and child connectingDjango ORM,父子连接
【发布时间】:2022-01-27 04:23:34
【问题描述】:

Django ORM

万事如意,

希望大家都好。

我有两个表我正在寻找加入并努力以特定方式加入。

我可以使用 SQL 轻松加入它们,但我更愿意使用 Django。

以下型号;

孩子:

    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

家长:

    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。

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

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

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

目前我无法将父数据加入到子数据中,我尝试了一些不同的方法,但在原始 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') 但是当我这样做时出现错误。

"raise 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

非常感谢任何帮助。

提前致谢, 汤姆

【问题讨论】:

  • 你能包含你的原始 sql 查询吗?
  • 补充说,我意识到我不需要过滤优惠资格对象,如果它不等于优惠PK,那么它需要是0/null/None。这将向用户显示员工不在报价中,这意味着他们可以包含或不包含他们。我想使用 Django ORM 的原因是因为我想使用 django-filters。
  • employee.objects.filter(client=clientpk).annotate(somecol=F('offer_eligibility__amount_offered')) 到目前为止我已经得到了这个,因为至少现在我得到了加入正确的方式。嗯
  • 让它在 django-tables2 中工作,但现在我只需要过滤注释。我非常接近答案,一旦我得到它就会发布它。

标签: python sql django django-models django-orm


【解决方案1】:

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

我觉得我现在对 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 但我只想在员工在报价中时添加值,因此,我需要使用 case 函数,如果您正在查看我的问题并需要类似的帮助,绝对建议您阅读条件表达式。

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

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

【讨论】:

  • 这并没有解决问题.. 我现在有同一个员工的多条记录...如果有超过 1 个报价,我如何在不创建重复行的情况下进行注释?
猜你喜欢
  • 2014-02-16
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 2020-05-18
  • 1970-01-01
  • 2019-03-15
  • 2011-12-15
相关资源
最近更新 更多