django rest api - добавление пользователей в модель ключевых слов - PullRequest
0 голосов
/ 27 июня 2018

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

, поэтому, если пользователи отправляют запрос с ключевым словом внутри, объект пользователя будет добавлен по предопределенному ключевому слову (предопределено в базе данных).

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

будет добавлено ключевое слово, но не предоставленные данные json, это просто пустая строка, а запрос на публикацию возвращает также пустое ключевое слово ...

Я надеюсь, что вы сможете мне помочь, и, возможно, вы могли бы дать мне совет, как просто разрешить статические ключевые слова, которые уже определены, и разрешить пользователю иметь ключевое слово только один раз (без двойных ключевых слов с одинаковым значением)

Сделано с такими заголовками:

[{"key":"Content-Type","value":"application/json","description":""}]
[{"key":"Authorization","value":"Token xxxxxxx","description":""}]

Body:
{
"name": "keyword1"
}

Авторизация работает, поэтому пользователь добавил пустое ключевое слово

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

Это фрагменты для реализации:

models.py

class Keywords(models.Model):
    name = models.CharField(max_length=200)
    user = models.ManyToManyField(User)

    def __str__(self):
        return self.name

serializers.py

class KeywordSerializer(serializers.Serializer):
    class Meta:
        model = Keywords
        fields = ('id', 'name', 'user')

    def create(self, validated_data):
            keyword = Keywords(**validated_data)
            keyword.save()
            keyword.user.add(self.context['request'].user)
            return keyword

views.py

class KeywordAPI(generics.RetrieveAPIView):
    permission_classes = [permissions.IsAuthenticated, ]
    serializer_class = KeywordSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        keyword = serializer.save()
        return Response({
            "name": KeywordSerializer(keyword, context=self.get_serializer_context()).data,
        })

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Попробуйте этот фрагмент:


class KeywordSerializer(serializers.<b>ModelSerializer</b>):
    <b>user = serializers.HiddenField(default=serializers.CurrentUserDefault())</b>

    class Meta:
        model = Keywords
        <b>fields = '__all__'</b>

    <b>def create(self, validated_data):
        user = validated_data.pop('user')
        kw = Keywords.objects.create(**validated_data)
        kw.user.add(user)
        kw.save()
        return kw</b>

и views:

from rest_framework import viewsets, permissions

class KeywordAPI(viewsets.ModelViewSet):
    permission_classes = [permissions.IsAuthenticated, ]
    serializer_class = KeywordSerializer
    queryset = Keywords.objects.all()

Входная полезная нагрузка будет

{
"name":"kw1"
}

Примечание
Здесь я использовал класс ModelSerializer , потому что он очень удобен для приложений CURD и HiddenField - это что-то вроде параметра write_only=True для полей.

Ссылки:

  1. DRF - модель просмотра
  2. * 1030 скрытое *
  3. CurrentUserDefault
0 голосов
/ 27 июня 2018

Для тех, у кого может быть такая же проблема, вот полное решение: Спасибо Сардорбеку Имомалиеву и Джерину Петру Георгию за помощь

сериализатору:

class KeywordSerializer(serializers.ModelSerializer):
users = serializers.HiddenField(default=serializers.CurrentUserDefault())

class Meta:
    model = Keyword
    fields = '__all__'

def create(self, validated_data):
    users = validated_data.pop('users')
    if Keyword.objects.filter(**validated_data).exists():
        kw = Keyword.objects.filter(**validated_data).get()
        kw.users.add(self.context['request'].user)
        return kw
    else:
        raise serializers.ValidationError("This Keyword has not been set yet.")

Модель:

class Keyword(models.Model):
name = models.CharField(max_length=200)
users = models.ManyToManyField(User)

def __str__(self):
    return self.name

вид:

class KeywordAPI(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated, ]
serializer_class = KeywordSerializer
queryset = Keyword.objects.all()
0 голосов
/ 27 июня 2018

Есть несколько вещей, которые вы делаете неправильно

Первый Имя вашей модели - Keywords, оно не должно быть множественным, используйте Keyword, а поле user - ManyToMany, поэтому вы должны использовать его как множитель

class Keyword(models.Model):
    name = models.CharField(max_length=200)
    users = models.ManyToManyField(User)

    def __str__(self):
        return self.name

Второй Вы используете Serializer вместо ModelSerializer

class KeywordSerializer(serializers.ModelSerializer):
    class Meta:
        model = Keywords
        fields = ('id', 'name', 'users')
        read_only_fields = ('users',)

    def create(self, validated_data):
        keyword = super().create(validated_data)
        keyword.users.add(self.context['request'].user)
        return keyword

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

from rest_framework import mixins


class KeywordAPI(mixins.CreateModelMixin, generics.RetrieveAPIView):
    permission_classes = [permissions.IsAuthenticated, ]
    serializer_class = KeywordSerializer

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...