【问题标题】:Custom field Django Rest Framework自定义字段 Django Rest Framework
【发布时间】:2020-02-29 15:18:39
【问题描述】:

我正在处理一个位置项目,对于后端,我正在使用带有 PostgreSQL 的 Django Rest 框架。我正在获取以下格式的请求对象。

{"BatchId": 1, "GeoLocation": [{"latitude": 28.257999420166016, "longitude": 77.6415388}, {"latitude": 12.9562821, "longitude": 77.6415199}]}

我想将 GeoLocation 存储在字符串字段中,因此我使用 ($) 来分隔数组元素。例如:-

28.257999420166016**$**77.6415388

我已经为此创建了一个自定义字段,但它显示无效错误。

模型.py

class GeoLocation(models.Model):

    date = models.DateField()
    location = ArrayField(GeoLocationField())

地理位置字段

class GeoLocationField(models.Field):
    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        return parse_location(value)
    def get_prep_value(self, value):
        return '$'.join([''.join(l) for l in (value.latitude,value.longitude)])

def parse_location(point_string):
    args = point_string.split('$')
    if len(args) != 2:
        raise ValidationError(_("Invalid input for a Location instance"))
    return Location(*args)


class Location:

    def __init__(self, latitude, longitude):
        self.latitude = latitude
        self.longitude = longitude

或者有没有其他的存储方式?

【问题讨论】:

    标签: python postgresql django-rest-framework


    【解决方案1】:

    作为建议,您可以将其保留为 json 对象。 PostgreSQL 特定模型字段JSONField

    序列化器:

        class LocationSerializer(serializers.Serializer):
            latitude = serializers.FloatField(read_only=True)
            longitude = serializers.FloatField(read_only=True)
    
    
        class  GeoLocationSerializer(serializers.ModelSerializer):
           location = LocationSerializer(many=True)
    
           class Meta:
               model = GeoLocation
               fields = [date, location]
    
    

    型号:

        class GeoLocation(models.Model):
           date = models.DateField()
           location = JSONField()
    

    【讨论】:

    • 谢谢,但我们必须将纬度、经度标记为只读字段
    【解决方案2】:

    使用 Json 字段

    序列化器.py

    class JSONSerializerField(serializers.Field):
        """ Serializer for JSONField -- required to make field writable"""
    
        def to_internal_value(self, data):
            return data
    
        def to_representation(self, value):
            return value
    
    class GeoLocationSerializer(serializers.ModelSerializer):
        location = JSONSerializerField()
    
        class Meta:
            model = models.GeoLocation
            fields = ['id', 'location', 'date']
    

    模型.py

    class GeoLocation(models.Model):
        date = models.DateField(default=datetime.date.today)
        location = JSONField()
        entered_user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='+')
    

    【讨论】: