我有一个“抽象”模型类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/

10-12 00:49