2015-03-10 4 views
2

Я строю сериализатор в django с использованием рамки django rest. Мне нужно отфильтровать набор запросов для вложенной модели.Фильтр на вложенном сериализаторе в каркасе отдыха django

Я нашел How do you filter a nested serializer in Django Rest Framework?, у которого, казалось, был ответ, но когда я его осуществил, никаких изменений в моих данных не было. Единственное различие, которое я вижу, это то, что сериализатор, ссылающийся на сериализатор фильтрованных списков, имеет и другие поля.

модели (сокращенно для ясности):

class GCUser(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    email = models.EmailField() 
    is_member = models.BooleanField(default=False) 
    age = models.SmallIntegerField(blank=True, null=True) 
    session_key = models.CharField(max_length=100, db_index=True, blank=True, null=True) 


class Connection(models.Model): 
    creation_date = models.DateTimeField(auto_now_add=True) 
    user = models.ForeignKey(GCUser, related_name='user_connection') 
    event = models.ForeignKey(Event, related_name='event_connection') 
    role = models.CharField(max_length=8, choices=constants.Roles.ROLE_CHOICES,) 

class Event(Game): 
    creation_date = models.DateTimeField(auto_now_add=True) 
    public = models.BooleanField(default=False) 
    start_time = models.DateTimeField(null=True, blank=True) 
    end_time = models.DateTimeField(null=True, blank=True) 
    gm_is_player = models.BooleanField(default=False, 
             help_text='Check if GM will be playing the game', 
             verbose_name='GM is a player') 
    gm_is_designer = models.BooleanField(default=False, help_text='Check if GM designed the game') 
    user_notes = models.TextField(blank=True, default='', verbose_name='Note to Scheduler') 
    scheduler_notes = models.TextField(blank=True, default='') 
    experience = models.CharField(max_length=3, choices=constants.ExpLevels.EXPERIENCE_CHOICES, 
            default=constants.ExpLevels.NOVICE,) 
    status = models.CharField(max_length=4, db_index=True, 
           choices=constants.Status.STATUS_CHOICES,) 

Вот мой код:

class FilteredListSerializer(serializers.ListSerializer): 
    def to_representation(self, data): 
     data = data.filter(status=constants.Status.ASSIGNED).order_by('start_time') 
     return super(FilteredListSerializer, self).to_representation(data) 


class UserEventSerializer(serializers.ModelSerializer): 
    class Meta: 
     list_serializer_class = FilteredListSerializer 
     model = models.Event 
     fields = ('id', 'event_name', 'conflict_type', 'start_time', 'end_time') 


class UserConnectionSerializer(serializers.ModelSerializer): 
    event = UserEventSerializer() 

    class Meta: 
     model = models.Connection 
     fields = ('get_role_display', 'conflict_type', 'event') 


class GCUserSerializer(serializers.ModelSerializer): 
    user_connection = UserConnectionSerializer(many=True) 

    class Meta: 
     model = models.GCUser 
     fields = ('pk', 'first_name', 'last_name', 'email', 
        'is_member', 'age', 'user_connection') 

PyCharm говорит мне, что «класс FilteredListSerializer должен реализовать все абстрактные методы», но это на самом деле не бросают ошибка. Я поставил точку останова в первой строке сериализатора списка, но она не сработала.

Я использую Python 3.4 с django 1.7.

Заранее за вашу помощь.

Отредактировано для добавления: Заглянув в код сериализатора, я понял, каково может быть ключевое различие: мой звонок имеет many=True, тогда как тот, который был из предыдущего сообщения, не сделал. Я попытался вытащить model=, но, как и ожидалось, выбросил ошибку, так что, по-видимому, «рабочий» код в более раннем сообщении фактически не запускался, как написано.

+0

Из вашего примера кажется, что нет модели, которая вложена для сериализации. Не могли бы вы объяснить, какую родственную модель вы хотите фильтровать и сериализовать? – jnishiyama

+0

Я отредактировал OP, чтобы включить модели и всю цепочку сериализаторов. –

+0

У меня была такая же проблема только сейчас. Первоначально, когда я писал свой сериализатор, абстрактного предупреждения не было, но сегодня оно есть. Я не знаю, как это исправлено, но я выполнил недействительный кеш и перезапустил на pycharm, и предупреждение исчезло. – sirFunkenstine

ответ

1

Так что я не знаю, как использовать метод, который вы используете, но, если я правильно понимаю ваш вопрос, я полагаю, вы могли бы сделать что-то вроде этого:

class UserEventSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = models.Event 
     fields = ('id', 'event_name', 'conflict_type', 'start_time', 'end_time') 

    class UserConnectionSerializer(serializers.ModelSerializer): 
    event = serializers.SerializerMethodField() 

    class Meta: 
     model = models.Connection 
     fields = ('get_role_display', 'conflict_type', 'event') 

    def get_event(self, obj): 
     if obj.event.status == constants.Status.ASSIGNED: 
     serializer = UserEventSerializer(obj.event) 
     return serializer.data 
     else: 
     serializer = UserEventSerializer(None) 
     return serializer.data 

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

Надеюсь, это поможет. Если я не понял проблему, сообщите мне.

+0

К сожалению, я все еще вижу события со статусом, отличным от Assigned. Я думаю, вы понимаете проблему. Я вижу, что ваш код должен делать, и это то, что я хочу. –

+0

Глядя на это снова, я понял, что пропустил одно из предложенных вами изменений. Собираем в результате в следующем: Тип исключения: \t AssertionError Исключение Значение: \t Это является излишним указать «get_event» на «событие» SerializerMethodField в сериализатором «UserConnectionSerializer», потому что она такая же, как имя метода по умолчанию , Удалите аргумент 'method_name'. –

+0

Я отредактировал свой ответ, чтобы удалить аргумент «method_name», работают ли изменения? – jnishiyama

Смежные вопросы