Django代理字段

问题描述 投票:8回答:1

是否有可能创建一个Django代理字段,该字段可以访问另一个字段,但是不会为数据库保存任何内容以获取它自己的值,并且没有自己的数据库列?

这个用例是我们想在JsonField中存储值,但是能够使用Django Fields的内置验证。这样做的第二个好处是能够添加新字段(具有验证功能)而不会影响数据库架构。

sudo代码可能看起来像这样:

from django.db import models
from django.contrib.postgres.fields import JsonField

class ProxyInitMixin(object):

    def __init__(self, *args, *kwargs):
        # some logic that will hold values if set on the Model
        # but won't create a column or save anything to the
        # database for this Field.
        super(ProxyInitMixin, self).__init__(*args, **kwargs)

class ProxyIntegerField(ProxyInitMixin, models.Field):
    pass

class ProxyCharField(ProxyInitMixin, models.Field):
    pass

class MyModel(models.Model):
    proxy_int = ProxyIntegerField()
    proxy_char = ProxyCharField()
    data = JsonField()

    def save(self, *args, **kwargs):
        self.data = {
            'foo': self.proxy_int,
            'bar': self.proxy_char
        }
        return super(MyModel, self).save(*args, **kwargs)
python django
1个回答
1
投票

django中有代理模型,但我不确定它是否有类似代理字段的东西。

对于您的用例,您可以按照以下说明进行操作:

  1. 创建一个字段列表,每个字段包含name,type,nullable等。
  2. 在模型中添加一个函数以返回实际的django rest框架(DRF)字段类实例,对应于传递给它的每个字段类型。
  3. 使用DRF内置字段类验证来根据save()中的指定字段类型验证字段数据。
  4. 除了自动验证,您还将获得自动类型转换。例如。如果用户输入数字1作为文本:“1”表示整数字段,则它会自动将其转换回整数1.同样,它将适用于float,Bool,Char等

`

from django.db import models
from rest_framework.fields import IntegerField, FloatField, BooleanField, DateTimeField, CharField

class MyModel(models.Model):
    FIELDS = [{'field_name': 'proxy_int', 'field_type': 'int', 'null_allowed': 'True'},
              {'field_name': 'proxy_char', 'field_type': 'string', 'null_allowed': 'True'}]

    data = JsonField()

    def field_type(self, field):

        if field.field_type == 'int':
            return IntegerField()
        elif field.field_type == 'float':
            return FloatField()
        elif field.field_type == 'bool':
            return BooleanField()
        elif field.field_type == 'date':
            return DateTimeField()
        elif self.value_type == 'string':
            return CharField()
        return CharField()

    def save(self, *args, **kwargs):
        data = kwargs.get('data', {})
        new_data = {}

        for (field in FIELDS)

            field_name = field['field_name']
            field_type = field['field_type']
            field_value = data.get(field_name, None)

            validated_value = self.field_type(field_type).run_validation(field_value)

            new_data[field_name] = validated_value

        kwargs['data'] = new_data
        return super(MyModel, self).save(*args, **kwargs)`

如果需要,您可以尝试找出django的字段类(而不是DRF)并使用它们进行验证。

您可以继承此新MyModel类,以在其他模型中实现类似功能并重用代码。

© www.soinside.com 2019 - 2024. All rights reserved.