【问题标题】:Is there a way to get the columns from a joined table in the model instance dict object?有没有办法从模型实例 dict 对象中的连接表中获取列?
【发布时间】:2020-11-22 11:14:59
【问题描述】:
t = PurchaseHeader.objects.first()
t.__dict__
{
  '_state': <django.db.models.base.ModelState object at 0x7f4b34aa7fa0>, 
  'id': 3, 
  'ref': 'jhkh', 
  'goods': Decimal('-100.00'), 
  'discount': Decimal('0.00'), 
  'vat': Decimal('-20.00'), 
  'total': Decimal('-120.00'), 
  'paid': Decimal('-120.00'), 
  'due': Decimal('0.00'), 
  'date': datetime.date(2020, 11, 7), 
  'due_date': datetime.date(2020, 11, 14), 
  'period': '202007', 
  'status': 'c', 
  'created': datetime.datetime(2020, 11, 7, 15, 46, 48, 191772, tzinfo=<UTC>), 
  'cash_book_id': None, 
  'supplier_id': 1128, 
  'type': 'pc'
}

当我加入供应商表时,我很失望地发现这些列未包含在字典中。下面,t.__dict__ 同上。我注意到供应商模型实例缓存在t._state 中,所以我想我可以创建自己的方法,所有模型都从该方法继承来执行我想要的操作 - 字典中所有表的所有列。但我想知道是否有人知道开箱即用的方法?

t = PurchaseHeader.objects.select_related("supplier").first()
t.__dict__

【问题讨论】:

    标签: django django-models django-orm


    【解决方案1】:

    select_related 的目标实际上是预取数据,这样在访问"supplier" 时就不需要在第二次查询中获取数据。相反,它已经使用原始查询中的连接获取了这些数据。

    如果你想基于你的模型获得一个dict,其中还包含一个关系的数据,你最好的办法是使用带有嵌套序列化程序的ModelSerializer。假设您的供应商模型称为Supplier,它看起来像这样:

    class SupplierSerializer(serializers.ModelSerializer):
        class Meta:
            model = Supplier
            fields = ['name', 'other_field'] # Add more Supplier fields
    
    class PurchaseHeaderSerializer(serializers.ModelSerializer):
        supplier = SupplierSerializer(read_only=True)
    
        class Meta:
            model = PurchaseHeader
            fields = ['supplied', 'vat', 'total'] # Add more PurchaseHeader fields
    

    然后您可以像这样使用PurchaseHeaderSerializer

    purchase_header = PurchaseHeader.objects.select_related("supplier").first()
    the_dict_you_want = PurchaseHeaderSerializer(instance=purchase_header).data 
    

    【讨论】:

    • 谢谢,尽管这显然取决于项目可能没有安装的 django rest 框架。我之所以问,是因为我对 django 还没有提供一种简洁的方法来做到这一点感到惊讶/失望。
    • 公平地说,您确实需要 DRF 才能使用此解决方案。我想您也可以为您的PurchaseHeader 类实现__repr__,并在标题和供应商上使用__dict__ 构造您想要的dict,并将供应商的结果放在标题dict 中。可以用2-3行代码完成。但是,根据您的项目将变得有多大,我认为 DRF 可能是一个更好的解决方案。
    猜你喜欢
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 2017-04-27
    • 2011-06-12
    • 1970-01-01
    相关资源
    最近更新 更多