Условно запретить Django объединяться с прикованными сериализаторами - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть сериализатор, requirementsSerializer, который выбирает две цепочки таблиц, comments и relatedfiles.В моем views.py я знаю, как условно фильтровать связанные таблицы, если пользователь вошел в систему. Что меня смущает, так это как исключить / предотвратить цепочку / присоединение, если пользователь НЕ вошел в систему. Прямо сейчас,он возвращает полный набор relatedfiles для всех пользователей, если пользователь не вошел в систему, что, очевидно, является проблемой безопасности.Я знаю, что мог бы создать второй сериализатор, который не объединяет другие таблицы, но не выглядит эффективным или чистым.

// serializers.py

class RequirementsSerializer(serializers.ModelSerializer):
    relatedfiles_set = RelatedFileSerializer(many=True, read_only=True)
    comments_set = CommentsSerializer(many=True, read_only=True)

    class Meta:
        model = Controls
        fields = ('id', 'sorting_id', 'relatedfiles_set', 'comments_set', 'requirement', 'requirement_section', 'requirement_subsection', 'requirement_version')

// views.py

if request.user.is_authenticated():
    queryset = Controls.objects.filter(requirement_version=requirement).filter(relatedfiles__team=request.user.team_id)
else:
    queryset = Controls.objects.filter(requirement_version=requirement) 

1 Ответ

1 голос
/ 24 сентября 2019

Если вы не хотите создавать другой сериализатор, вы можете разрешить динамическое изменение его полей, как показано в примере ниже.

https://www.django -rest-framework.org / api-guide / serializers/ # пример

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""

def __init__(self, *args, **kwargs):
    # Don't pass the 'fields' arg up to the superclass
    fields = kwargs.pop('fields', None)

    # Instantiate the superclass normally
    super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

    if fields is not None:
        # Drop any fields that are not specified in the `fields` argument.
        allowed = set(fields)
        existing = set(self.fields)
        for field_name in existing - allowed:
            self.fields.pop(field_name)

Теперь вы можете передать подмножество полей, если пользователь не аутентифицирован

if request.user.is_authenticated():
    RequirementsSerializer(instance)
else:
    RequirementsSerializer(instance, fields=('comments_set',)) # excluding relatedfiles_set

Если вы не создаете экземпляр Serializer явно, вы можете переопределитьметод get_serializer представления, который должен вернуть экземпляр Serializer и поместить туда условное выражение.

def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()

    if not self.request.user.is_authenticated():
        kwargs['fields'] = ('comments_set',)

    return serializer_class(*args, **kwargs)
...