gpt4 book ai didi

python - 将属性转换为 Django 模型字段

转载 作者:太空狗 更新时间:2023-10-30 03:06:40 25 4
gpt4 key购买 nike

有什么方法可以在 Django 中创建虚拟模型字段吗?

比如我有

class A(models.Model):
field_1 = models.CharField(max_length=100)
field_2 = models.CharField(max_length=100)

@apply
def virtual_field():
def fget(self):
return self.field1 + '/' + self.field2
def fset(self, value):
self.field_1, self_field_2 = value.split('/')
return True
return property(**locals())

现在,如果我要运行:

a = A()
a.virtual_field = '5/5'
a.save()

它会很好地工作。

但是我有一个转储,其中模型 A 具有 virtual_field 值 - 在序列化时出现错误“对象没有 virtual_field”...我如何欺骗序列化程序并告诉它 virtual_field 存在?

最佳答案

如果您想从遗留夹具加载,您可以构建一些中间模型/表、转换文件或自定义 dumpdata 命令。傻瓜转储数据是可以的,如下,但是嗯...

class VirtualField(object):
rel = None

def contribute_to_class(self, cls, name):
self.attname = self.name = name
# cls._meta.add_virtual_field(self)
get_field = cls._meta.get_field
cls._meta.get_field = lambda name, many_to_many=True: self if name == self.name else get_field(name, many_to_many)
models.signals.pre_init.connect(self.pre_init, sender=cls) #, weak=False)
models.signals.post_init.connect(self.post_init, sender=cls) #, weak=False)
setattr(cls, name, self)

def pre_init(self, signal, sender, args, kwargs, **_kwargs):
sender._meta._field_name_cache.append(self)

def post_init(self, signal, sender, **kwargs):
sender._meta._field_name_cache[:] = sender._meta._field_name_cache[:-1]

def __get__(self, instance, instance_type=None):
if instance is None:
return self
return instance.field1 + '/' + instance.field2

def __set__(self, instance, value):
if instance is None:
raise AttributeError(u"%s must be accessed via instance" % self.related.opts.object_name)
instance.field1, instance.field2 = value.split('/')

def to_python(self, value):
return value

class A(models.Model):
field1 = models.TextField()
field2 = models.TextField()
virtual_field = VirtualField()

# legacy.json
[{"pk": 1, "model": "so.a", "fields": {"virtual_field": "A/B"}}, {"pk": 2, "model": "so.a", "fields": {"virtual_field": "199/200"}}]

$ ./manage.py loaddump legacy.json
Installed 2 object(s) from 1 fixture(s)

或者您可以将自定义序列化器添加到公共(public)序列化器,并主要覆盖其 Deserializer 函数以使用您拥有的属性。主要重写以调整 django/core/serializers/python.py

内的 Deserializer 中的两行
field = Model._meta.get_field(field_name)
# and
yield base.DeserializedObject(Model(**data), m2m_data)

关于python - 将属性转换为 Django 模型字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7501557/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com