我有一个Django项目的一部分,该项目涉及将公寓应用程序提交到系统中,并且我注意到使用ORM查找应用程序,然后将该对象转换为调用__dict__
的字典以进行-填充表格。
我很好奇,是否有人可以解释正在发生的事情或我做错了什么。基本上,我的UnitApplication
模型中有一个外键,因此应用程序被映射到属性,该数据库列名和模型中的属性名是property_id
,但是当我将对象变成字典时,在字段名称后附加一个_id
。
这是我的代码:
application_id = request.GET.get('application_id')
application = UnitApplication.objects.using(db_alias).get(id=application_id)
# this is in a view so property_id == Property Object (1)
print(application.property_id)
# this will print my actual property_id, which is 1
print(application.property_id.id)
# this is the odd behavior, here is the dict that prints, and hinders form filling
# {..., 'property_id_id': 1, ...}
print(application.__dict__)
这是怎么回事?我可以通过编辑dict来解决此问题,但是我感觉这是个问题。
如果您对我的命名感到好奇,以下是我的模型的相关部分:
class Property(models.Model):
# I know this isn't needed but it makes me feel better seeing it here
id = models.AutoField(primary_key=True)
rental_add_ons = models.ManyToManyField('RentalAddOns', related_name='rental_add_ons')
date_added = models.DateTimeField(auto_now_add=True, editable=False)
...
class UnitApplication(models.Model):
# property id, set to null if property removed from db
property_id = models.ForeignKey('Property',
null=True,
on_delete=models.SET_NULL,
db_column='property_id')
注意:我为此使用常规的Form
,因为它为我提供了更大的自由度,我不希望寻求使用{{1} },我已经做到了,尽管这个问题没有在那儿发生,但对于我的需求而言并不理想。
答案 0 :(得分:1)
只想分享一种我想出的方法,可以使用Django的内置功能将对象变成字典。从这里的评论和答案看来,我不应该使用__dict__
。
from django.forms import model_to_dict
application = UnitApplication.objects.get(id=request.GET.get('application_id'))
accurate_dictionary = model_to_dict(application)
print(accurate_dictionary)
现在可行:
form = UnitApplicationForm(initial=accurate_dictionary)
答案 1 :(得分:0)
我的建议是实现一种以所需格式返回所需字段的方法。 __dict__
并不意味着可以直接访问,并且可能有一些内部操作导致您看到不一致的地方。
答案 2 :(得分:0)
您的问题是您在primary_id
中命名了字段UnitApplication
。 Django会自动将_id
附加到任何外键字段中,因此您可以使其变得多余。如果您查看实际的数据库,则可以看到列名也将是property_id_id
。
要解决此问题,您可以将property_id
字段重命名为property
,然后重新迁移。
答案 3 :(得分:0)
比__dict__
更好的方法可能是使用values()
,它返回字典而不是模型对象的查询集,或者使用model forms。
在模型中定义外键时Django的作用是:它将引用对象的主键保存在数据库表的<field_name>_id
列中。
由于您将ForeignKey
字段命名为property_id
,因此Django在数据库中创建了一个property_id_id
列,用于保存外键。 (很明显,为什么约定要求在它们引用的模型之后命名外键字段,而不添加_id
,在这种情况下为property
。)
您可以在任何UnitApplication
对象上访问此属性。以下内容将为true:
unitapp.property_id_id == unitapp.property_id.id
在两种情况下,您都将访问相关对象的主键,一次是从主模型,一次是从相关模型。
在模型对象上调用__dict__
时,外键仅表示为id,其键为列名。您没有实际相关对象的句柄。