我有一个“抽象”模型类MyField:
class MyField(models.Model):
name = models.CharField(db_index = True, max_length=100)
user = models.ForeignKey("AppUser", null=False)
我还有MyField的其他几个子类,每个子类定义特定类型的值。
例如:
class MyBooleanField(MyField):
value = models.BooleanField(db_index = True, default=False)
在MyField中,我有一个get_value()方法,该方法根据特定的子类返回值。
在Django Rest中,我想获取用户的所有字段
class AppUserSerializer(serializers.ModelSerializer):
appuserfield_set = MyFieldSerializer(many=True)
class Meta:
model = AppUser
fields = ('appuser_id', 'appuserfield_set')
在客户端,我希望用户能够添加新字段并为其设置值,然后在服务器上,我希望能够基于该值创建正确的字段。
实现此行为的正确方法是什么?
最佳答案
经过一番挖掘,这就是我最终要做的。除了下面的代码,我还必须实现get_or_create并根据传递的值创建MyField的相关子类。
class ValueField(serializers.WritableField):
#called when serializing a field to a string. (for example when calling seralizer.data)
def to_native(self, obj):
return obj;
"""
Called when deserializing a field from a string
(for example when calling is_valid which calles restore_object)
"""
def from_native(self, data):
return data
class MyFieldSerializer(serializers.ModelSerializer):
value = ValueField(source='get_value', required=False)
def restore_object(self, attrs, instance=None):
"""
Called by is_valid (before calling save)
Create or update a new instance, given a dictionary
of deserialized field values.
Note that if we don't define this method, then deserializing
data will simply return a dictionary of items.
"""
if instance:
# Update existing instance
instance.user = attrs.get('user', instance.user)
instance.name = attrs.get('name', instance.name)
else:
# Create new instance
instance = MyField.get_or_create(end_user=attrs['user'],
name=attrs['name'],
value=attrs['get_value'])[0]
instance.value = attrs['get_value']
return instance
def save_object(self, obj, **kwargs):
#called when saving the instance to the DB
instance = MyField.get_or_create(end_user=obj.user,
name=obj.name,
value=obj.value)[0]
class Meta:
model = MyField
fields = ('id', 'user', 'name', 'value')
关于python - Django Rest框架和模型继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22654952/