[英]Python/Django Strange behavior with object dictionary and __dict__
我有一个Django项目的一部分,该项目涉及将单元应用程序提交到系统中,并且我注意到使用ORM查找应用程序,然后将该对象转换为调用__dict__
的dict以预填充表单的奇怪行为。
我很好奇是否有人可以解释正在发生的事情或我做错了什么。 基本上,我的UnitApplication
模型中有一个外键,因此应用程序被映射到Properties,这个数据库列名和Model中的属性名是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
,因为它为我提供了更多的自由,我没有寻求关于更改此范围以使用Model Form
建议,尽管这样做并没有发生,这对我的需求而言并不理想。
只是想分享一种我想出的方法,可以使用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)
我的建议是实现一种以所需格式返回所需字段的方法。 __dict__
并不意味着可以直接访问,并且可能会有一些内部操作导致您看到不一致的情况。
您的问题是您在UnitApplication
字段命名为primary_id
。 Django会自动将_id
附加到任何外键字段中,因此您可以做到这一点使其变得多余。 如果查看实际数据库,则可以看到列名也将是property_id_id
。
要解决此问题,您可以将property_id
字段重命名为property
,然后重新迁移。
比__dict__
更好的方法可能是使用values()
,它返回字典的查询集而不是模型对象,或者使用模型form 。
在模型中定义外键时,Django的作用是:将引用对象的主键保存在数据库表的<field_name>_id
列中。
由于您将ForeignKey
字段命名为property_id
,因此Django在数据库中创建了一个property_id_id
列,用于保存外键。 (很明显,为什么约定要求在它们引用的Model之后命名外键字段,而在本例中为property
而不添加_id
。)
您可以在任何UnitApplication
对象上访问此属性。 以下内容将评估为true:
unitapp.property_id_id == unitapp.property_id.id
在这两种情况下,您都将访问相关对象的主键,一次是从主模型中,一次是从相关模型中。
当您在模型对象上调用__dict__
时,外键仅表示为ID,其键为列名。 您没有获得实际相关对象的句柄。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.