Django复制记录的方法
最近的Django项目中有复制记录的需求。数据库里有一张名为Party的表,记录用户创建的party,现在要让用户能够复制一个新的party。本身非常简单的一个功能,但运行的时候出错了。我以为是复制过程出错,所以测试了一下Django中复制记录可能遇到的情况(后来发现是其他代码的逻辑出了问题),结果整理如下。
1.Reset pk
在Django中复制一条记录最简单的方法应该是先取出这条记录,将它的主键设置为None,然后再保存一次。
1
2
3
|
old_party = Party.objects.get(pk=1)
party.pk = None
party.save()
|
2.Keyword Arguments
如果某张表除了主键还有其他AutoField字段,就要换一种方式了,虽然也可以手动根据字段名将其指定为空,但直接遍历出字段名和相应的值,把其中的AutoField字段赋值为None会比较简单。
1
2
3
4
5
6
7
8
|
data = {}
for f in old_party._meta.fields:
if f.__class__.__name__ != 'AutoField':
data[f.name] = getattr(old_party, f.name)
else:
data[f.name] = None
party = Party(**data)
party.save()
|
3.Deepcopy
Django没有直接复制记录的方法,但是Python提供了copy模块用来拷贝一个对象,所以也可以这样复制Django的记录:
1
2
3
4
|
import copy
party = copy.deepcopy(old_party)
party.pk = None
party.save()
|
Except
在关系型数据库中,存在相关联的表是很常见的事。Django中有三种关系型字段:ForeignKey/ManyToManyField/OneToOneField,这些就是需要例外处理的情况了。
ForeignKey在数据库中是用整数型来存放id,所以只要清空主键,直接保存也不会出错。假设party有一个外键关联到creator,如果要把这个关联的外键也复制一份,可以直接Deepcopy:
1
2
3
|
creator = copy.deepcopy(party.creator)
creator.pk = None
creator.save()
|
OneToOneField一般都是处理用户Profile和其他比较特殊的数据,所以还没有遇到过要复制OneToOneField的情况,纯测试了一下,前面提供的方法就可以解决,这里就不赘述了。
ManyToManyField比较特殊,关联的一般是多条记录,需要做一些处理:
1
2
3
4
|
creator = party.creator.all()
party.pk = None
party.save()
party.creator = creator
|
作者:子钦加油
出处:https://www.cnblogs.com/zmdComeOn/
个性签名:努力生活,努力走路
阿里云拼团:https://www.aliyun.com/1111/home?userCode=f4ee1llo1核2G1M,86一年,229三年;2核4G5M,799三年;2核8G5M,1399三年
腾讯云三月采购计划特价:https://cloud.tencent.com/act/cps/redirect?redirect=1073&cps_key=15d0b1673287c43fe946626d9f4e2eee&from=console1核2G1M,88一年;1核2G1M,268三年;2核4G5M,998一年;4核8G5M,2888元三年
出处:https://www.cnblogs.com/zmdComeOn/
个性签名:努力生活,努力走路
阿里云拼团:https://www.aliyun.com/1111/home?userCode=f4ee1llo1核2G1M,86一年,229三年;2核4G5M,799三年;2核8G5M,1399三年
腾讯云三月采购计划特价:https://cloud.tencent.com/act/cps/redirect?redirect=1073&cps_key=15d0b1673287c43fe946626d9f4e2eee&from=console1核2G1M,88一年;1核2G1M,268三年;2核4G5M,998一年;4核8G5M,2888元三年