Fur*_*tor 4 django django-models django-views
我有以下模型(def __unicode__(...)为了清楚起见,我遗漏了):
class Person(models.Model):
first_name = models.CharField(max_length=64, null=True, blank=True)
middle_name = models.CharField(max_length=32, null=True, blank=True)
last_name = models.CharField(max_length=64, null=True, blank=True)
class MinorResident(Person):
move_in_date = models.DateField(null=True)
move_out_date = models.DateField(null=True)
natural_child = models.NullBooleanField()
class OtherPerson(Person):
associate_all_homes = models.BooleanField(default=False)
Run Code Online (Sandbox Code Playgroud)
我有以下视图方法使用MinorResident对象来创建OtherPerson对象,如:
def MinorToAdult(request, minor):
p = Person.objects.get(id=minor.person_ptr_id)
o = OtherPerson(p.id)
o.__dict__.update(p.__dict__)
o.save()
return True
Run Code Online (Sandbox Code Playgroud)
这一切都很好,但我仍然在minoresident表中有一条记录,指向person_ptr_id的人员记录.我在otherperson表中也有一个指针记录,同一个person_ptr_id指向同一个人,并显示切换之前的所有数据,但是使用了OtherPerson对象而不是MinorResident对象.所以,我想删除MinorResident对象,而不删除父类Person对象.我想我可以这样做:
p = Person.objects.get(id=minor.person_ptr_id)
o = OtherPerson()
o.__dict__.update(p.__dict__)
o.save()
minor.delete()
return True
Run Code Online (Sandbox Code Playgroud)
但是如果我能帮助它,我想在Person表中没有新的记录,因为它真的不是一个新人,只是一个现在成年人的人.也许我可以这样做吗?还是有更好的方法来处理模型嬗变?
p = Person.objects.get(id=minor.person_ptr_id)
o = OtherPerson(p.id)
o.__dict__.update(p.__dict__)
o.save()
minor.person_ptr_id = None
minor.delete()
return True
Run Code Online (Sandbox Code Playgroud)
我看了#3711191:django-deletion-object-keeping-parent,但我希望得到一个改进的答案.
在Django 1.10.4+上,您可以使用以下keep_parents选项:
minor.delete(keep_parents=True)
Run Code Online (Sandbox Code Playgroud)
另外我建议您使用deletion.Collector手动收集:
from django.db.models import deletion
collector = deletion.Collector(using=minor._state.db)
collector.add([minor])
collector.delete()
Run Code Online (Sandbox Code Playgroud)
选项1
显式指定您的parent_link字段并使用非托管模型。
class MinorResident(Person):
person = models.OneToOneField(
Person,
parent_link = True,
primary_key = True,
db_column = 'person_id'
)
move_in_date = models.DateField(null=True)
move_out_date = models.DateField(null=True)
natural_child = models.NullBooleanField()
class UnmanagedMinorResident(models.Model):
person = models.OneToOneField(
Person,
primary_key = True,
db_column = 'person_id'
)
move_in_date = models.DateField(null=True)
move_out_date = models.DateField(null=True)
natural_child = models.NullBooleanField()
class Meta:
managed = False
db_table = MinorResident._meta.db_table
Run Code Online (Sandbox Code Playgroud)
UnmanagedMinorResident.delete()现在您可以在不删除父行的情况下调用。
选项#2
使用原始 SQL 查询
from django.db import connection
minor = # MinorResident object
c = connection.cursor()
table = MinorResident._meta.db_table
column = MinorResident._meta.pk.column
# In this specific case it is safe to not escape.
sql = "DELETE FROM {0} WHERE {1}={2}".format(table, column, minor.pk)
c.execute(sql)
Run Code Online (Sandbox Code Playgroud)
但您可能应该更改数据模型并对成人和未成年人使用相同的表。您存储在模型中的属性不属于该模型,它们属于模型与其移入/移出的实体MinorResident之间的关系。MinorResident
| 归档时间: |
|
| 查看次数: |
2620 次 |
| 最近记录: |