具有对象字典和__dict __

时间:2019-04-03 14:59:54

标签: python django python-3.x

我有一个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} },我已经做到了,尽管这个问题没有在那儿发生,但对于我的需求而言并不理想。

4 个答案:

答案 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,其键为列名。您没有实际相关对象的句柄。