2014-11-09 4 views
1

Моя цель - создать конечную точку, которая будет контролировать создание объектов модели с помощью GenericForeignKey. Так как модель также включает ContentType, фактический тип модели, о которой мы будем ссылаться, неизвестен до создания объекта.«Динамические» поля в сериализаторах DRF

Я приведу пример:

У меня есть «как» модель, которая может ссылаться на ряд других моделей, таких как «книги», «Автор».

class Like(models.Model): 
    created = models.DateTimeField() 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

Serializer может выглядеть следующим образом:

class LikeSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = models.Like 
     fields = ('id', 'created',) 

То, что я хочу добиться того, чтобы определить тип Подобраны на основе ключей, передаваемых в запросе. Проблема в том, что DRF не передает эти ключи из запроса, если они не были указаны в полех Serializer. Например, тело запроса POST содержит:

{ 
    "book":2 
} 

Я хочу сделать следующий

def restore_object(self, attrs, instance=None) 
    if attrs.get('book', None) is not None: 
     # create Like instance with Book contenttype 
    elif attrs.get('author', None) is not None: 
     # create Like instance with Author contenttype 

В этом случае первое, если условие будет выполнено. Как видите, тип определяется на основе ключа, переданного в запросе, без указания специального поля.

Есть ли способ достичь этого?

Благодаря

ответ

0

Вы можете попробовать инстанцирование вашего сериалайзера всякий раз, когда ваш взгляд называется окружив его функцию (вы делаете сериализатор завод):

def like_serializer_factory(type_of_like): 
    if type_of_like == 'book': 
     class LikeSerializer(serializers.ModelSerializer): 
      class Meta: 
       model = models.Like 
       fields = ('id', 'created',) 
      def restore_object(self, attrs, instance=None): 
       # create Like instance with Book contenttype 
    elif type_of_like == 'author': 
     class LikeSerializer(serializers.ModelSerializer): 
      class Meta: 
       model = models.Like 
       fields = ('id', 'created',) 
      def restore_object(self, attrs, instance=None): 
       # create Like instance with Author contenttype 
    return LikeSerializer 

Затем переопределить этот метод в целях:

def get_serializer_class(self): 
    return like_serializer_factory(type_of_like) 
Смежные вопросы