You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Django对象的部分属性值复制到新对象?

Django 复制对象部分属性的Pythonic实现方式

当你需要从现有Django模型对象继承部分属性创建新对象时,除了手动重置pk再逐个修改属性的方式,还有几种更符合Python风格的实现:

方法1:利用字典推导式+字典解包

直接从原对象的__dict__中筛选需要保留的属性,再更新要修改的字段,最后创建新对象:

objA = OBJ.objects.get(pk=objA_id)
# 排除内部状态字段和主键,保留其他属性
obj_data = {k: v for k, v in objA.__dict__.items() if k not in ['_state', 'id', 'pk']}
# 批量更新需要修改的属性
obj_data.update({
    'key1': value1,
    'key2': value2,
    'key3': None
})
# 字典解包创建新对象并保存
objB = OBJ(**obj_data)
objB.save()

这种方式通过Python的字典操作批量处理属性,比逐个赋值更简洁直观。

方法2:使用Django内置的model_to_dict

Django提供的model_to_dict函数会自动过滤模型的内部字段和不可编辑字段,比直接操作__dict__更安全:

from django.forms.models import model_to_dict

objA = OBJ.objects.get(pk=objA_id)
# 转换模型对象为属性字典
obj_data = model_to_dict(objA)
# 移除主键字段
obj_data.pop('id', None)
# 更新目标属性
obj_data.update({
    'key1': value1,
    'key2': value2,
    'key3': None
})
objB = OBJ(**obj_data)
objB.save()

model_to_dict会自动处理模型字段的规则,比如忽略editable=False的字段,避免手动筛选可能出现的遗漏。

方法3:封装为模型自定义方法(复用性更强)

如果需要频繁执行这类复制操作,可以把逻辑封装到模型类中,符合DRY原则:

from django.forms.models import model_to_dict
from django.db import models

class OBJ(models.Model):
    # 你的模型字段定义
    key1 = models.CharField(max_length=100)
    key2 = models.IntegerField()
    key3 = models.CharField(max_length=100, null=True)
    
    def copy_with_updates(self, **kwargs):
        # 指定需要复制的字段(可选,不指定则复制所有可编辑字段)
        base_data = model_to_dict(self, fields=['key1', 'key2', 'key3'])
        # 合并传入的修改参数
        base_data.update(kwargs)
        # 创建并保存新对象
        new_obj = OBJ(**base_data)
        new_obj.save()
        return new_obj

使用时只需一行代码:

objA = OBJ.objects.get(pk=objA_id)
objB = objA.copy_with_updates(key1=value1, key2=value2, key3=None)

这些方式相比原写法,避免了先修改原对象副本再覆盖属性的冗余操作,更符合Python的简洁性和可读性要求。

内容的提问来源于stack exchange,提问作者Empusas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:15:35