Получить зарегистрированную информацию о пользователях в сериализаторах Django Rest + Django JWT - PullRequest
0 голосов
/ 03 января 2019

Мне нужно получить информацию о FK в зарегистрированном пользователе на ModelSerializer, чтобы добавить новые модели.

В этом случае Пользователь-> Бизнес и Клиент-> Бизнес.При работе с почтовым клиентом мне нужно установить Business ID, используя зарегистрированного пользователя Business.

Важно сказать, что все другие модели ведут себя одинаково.Я ищу общее решение этой проблемы.

Модель клиента

class Client(SoftDeletionModel):
    object = ClientManager
    business = models.ForeignKey(Business, related_name='business_clients', on_delete=models.CASCADE)
    company_name = models.CharField(max_length=511, verbose_name=_('Company Name'))
    cnpj = models.CharField(max_length=14, verbose_name=_('CNPJ'))

Модель пользователя

class User(AbstractUser):
"""User model."""

    username = None
    email = models.EmailField(_('email address'), unique=True)
    business = models.ForeignKey(Business, related_name='business', on_delete=models.CASCADE, null=True)

ClientSerializer

class ClientSerializer(serializers.ModelSerializer):
    business = serializers.IntegerField() # here how can I get user.business?
    deleted_at = serializers.HiddenField(default=None)
    active = serializers.BooleanField(read_only=True)
    password = serializers.CharField(write_only=True, required=False, allow_blank=True)
    password_contract = Base64PDFFileField()

class Meta:
    model = Client
    fields = '__all__'
    validators = [
        UniqueTogetherValidator2(
            queryset=Client.objects.all(),
            fields=('cnpj', 'business'),
            message=_("CNPJ already exists"),
            key_field_name='cnpj'
        ),
        UniqueTogetherValidator2(
            queryset=Client.objects.all(),
            fields=('email', 'business'),
            message=_("Email already exists"),
            key_field_name='email'
        )
    ]

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Запрос доступа внутри сериализатора

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

class ClientSerializer(serializers.ModelSerializer):
    ...

    def create(self, validated_data):
        return Client.objects.create(
            business=self.context['request'].user.business,
            **validated_data
        )

Запрос доступен только в том случае, если вы передаете его при создании экземпляраserializer

Передача дополнительных аргументов в сериализатор через save()

Также возможно передать дополнительные аргументы в сериализатор во время вызова метода save()

def create(self, request, **kwargs)
    serializer = ClientSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    serializer.save(business=request.user.business)
    ...

Создание миксина для настройки бизнеса

Наконец, более подходящим способом является создание миксина для представлений, который обеспечивает действия create и / или update, затем перезапись perform_create() и perform_update() методов

class BusinessMixin:
    def perform_create(self, serializer):
        serializer.save(business=self.request.user.business)

    def perform_update(self, serializer):
        serializer.save(business=self.request.user.business)


class ClientViewSet(BusinessMixin, ModelViewSet):
    serializer_class = ClientSerializer
    queryset = Client.objects.all()
    ...

ModelViewSet (в основном CreateModelMixin и UpdateModelMixin) используют эти методы для вызова метода save() из сериализатора при выполнении его действий (create(), update() и partial_update(), т.е. POST, PUT и PATCH)

0 голосов
/ 04 января 2019

Вдохновлено serializers.CurrentUserDefault () magic Я написал CurrenUserBusinessDefault, но set_context с текущими пользовательскими операциями.

class CurrentUserBusinessDefault(object):
    def set_context(self, serializer_field):
        self.business =  serializer_field.context['request'].user.business

    def __call__(self):
        return self.business

    def __repr__(self):
        return unicode_to_repr('%s()' % self.__class__.__name__)

Так что он доступен как метод по умолчанию

class ClientSerializer(serializers.ModelSerializer):
    business = BusinessSerializer(default=CurrentUserBusinessDefault())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...