【问题标题】:Creating and saving non-empty Django model instance as part of subclass instance创建和保存非空 Django 模型实例作为子类实例的一部分
【发布时间】:2013-08-17 18:15:51
【问题描述】:

在创建和保存(插入数据库)模型实例时,我遇到了与 Django 文档不一致的非常奇怪的行为。由于可能的原因,我已经没有想法了,并且非常感谢任何建议为什么 Django 在这些情况下无法保存所有字段

我正在使用的这个类:

class Person(models.Model):
    user = models.ForeignKey(User)
    phone_number = models.CharField(max_length=20, blank=True)
    address     = models.CharField(max_length=200, blank=True)

这里的代码不起作用,少数情况:

# First Case
new_person = Person()
new_person.user = request.user
new_person.phone_number = '111111'
new_person.save(force_insert=True)

# Second One
new_person = Person(user=request.user, phone_number='111111')
new_person.save(force_insert=True)

# Third One 
new_person = Person.objects.create(user=request.user, phone_number='111111')

基于official Django docs 在任何情况下django 都应该创建一个对象并将其插入数据库。

事实上,对象已成功创建(并设置了所有相关字段),但插入 DB 的行仅正确填写了 iduser_id 字段,而同样设置的 phone_number 字段保持空白。

但是,访问和更新现有(之前保存的)对象的所有字段没有问题。

Person 类声明中删除blank=True(通过适当的表更改)不会改变任何内容。

编辑: 问题变得更加复杂。完整的描述和解决方案在下面我自己的答案中

【问题讨论】:

  • 第三个应该是Person.objects.create 而不是Person.objects.Create - 小写c
  • 当你删除blank=True时,就是对数据库表结构的改变。默认情况下,Django 不承认这一点。您将不得不删除数据库并使用 syncdb 重新创建(痛苦的..),或者运行更改表脚本以不允许空值。
  • @karthikr #1 感谢您的纠正,但这只是在这个问题中犯的一个小错误。#2 我应该提到它,但我也更改了表格中的 null 设置
  • @karthikr: blank=True 仅指表单字段,与数据库字段无关。 null=True 用于 db

标签: django django-models instance


【解决方案1】:

好的,我找到了解释......

它与继承有关,即在我想要创建 Person 子类的实例的代码中。于是又多了一个类:

class Person(models.Model):
    user = models.ForeignKey(User)
    phone_number = models.CharField(max_length=20, blank=True)
    address     = models.CharField(max_length=200, blank=True)

class ConnectedPerson(Person):
    connection = models.ForeignKey(AnotherClass)
    # etc..

在创建 Person 实例后,打算将其扩展到 ConnectedPerson,我编写了这样的代码:

#creating instance of Person:
person = Person(user=request.user, phone_number='111111')
person.save(force_insert=True)

c_person = ConnectedPerson(id=person.id, connection=instance_of_another_c)

使用ConnectedPerson(id=person.id) 实际上是通过在数据库中覆盖之前创建的 Person 实例来杀死它。


因此,对于在管理继承实例方面没有太多经验的人:如果您需要使用之前创建的超类实例作为子类实例的一部分,请这样做:

#creating person but not saving it
person = Person(user=request.user, phone_number='111111')

######
#later
###### 

#creating subclass instance and saving
c_person = ConnectedPerson(user=request.user, connection=instance_of_another_c)
c_person.save()

#saving super class instance as part of subclass instance
person.pk = super(ConnectedPerson, c_person).pk
person.save()

【讨论】:

    猜你喜欢
    • 2014-01-30
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 2023-03-23
    • 2015-10-20
    • 2017-02-01
    • 2011-05-03
    • 2013-02-11
    相关资源
    最近更新 更多