ModelViewSet: «это поле обязательно для заполнения», когда POST, поле FK - PullRequest
0 голосов
/ 01 июня 2019

Это мой текущий код

Модель:

class Author(models.Model):
    a_author= models.CharField( primary_key=True, unique=True, db_column='author_id')
    a_name = models.CharField(db_column='author_name')


class Book(models.Model):
    b_book = models.CharField( primary_key=True, unique=True, db_column='book_id')
    b_name = models.CharField(db_column='book_name')
    b_author = models.ForeignKey(
        Author,
        on_delete=models.CASCADE,
        db_column='book_author_name')

сериализаторы

class AuthorSerializer(serializers.ModelSerializer):
    author = serializers.CharField(source='a_author')
    name = serializers.CharField(source='a_name')
    class Meta:
        fields = ('author', 'name')

class BookSerializer(serializers.ModelSerializer):
    book = serializers.CharField(source='b_book')
    name = serializers.CharField(source='b_name')
    author = serializers.CharField(source='b_author')

    class Meta:
        fields = ('book', 'name', 'author')

    def create(self, validated_data):
        author_id = validated_data.pop('author')
        author = models.Author.objects.filter(a_author=author_id).first()
        validated_data['b_author'] = author
        return models.Book.objects.create(**validated_data)

Просмотры

class BookViewSet(viewsets.ModelViewSet):
     serializer_class = BookSerializer

     def get_queryset(self):
        queryset = models.Book.objects
        author = self.kwargs.get('author')
        queryset = queryset.filter(b_author=author)
        return queryset

1012 * Url *

urlpatterns = [
     path('library/<str:author_id>/', BookViewSet.as_view({'get': 'list', 'post':'create'}))
]

В настоящее время, если я отправлю сообщение на /library/123abc/ с параметрами: { 'name': 'test', 'author': '123abc' }, оно будет работать - будет создана запись Book с именем = test, author = 123abc.

Но теперь я хочу извлечь author из параметров (поскольку URL уже имеет идентификатор athor, поэтому я не хочу повторять его в параметрах) и отправить только {'name': 'test'}, он вернет 400 ошибку с сообщением {'author': 'this field is required'}. Я пробовал author = serializers.CharField(source='b_author', required=False), но это не сработало.

Есть ли способ обойти это? Интересно, есть ли способ включить дополнительное значение в django, прежде чем значение params будет проверено ...

1 Ответ

0 голосов
/ 03 июня 2019

Поскольку вы хотите, чтобы author отображался, но не записывался, вам нужно установить это поле как read_only:

class BookSerializer(serializers.ModelSerializer):
    book = serializers.CharField(source='b_book')
    name = serializers.CharField(source='b_name')
    author = serializers.CharField(source='b_author', read_only=True)

Далее, вы захотите сохранить author при создании Book. Для этого вам необходимо явно предоставить его сериализатору:

class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer

    def get_queryset(self):
        queryset = models.Book.objects
        author = self.kwargs.get('author')
        queryset = queryset.filter(b_author=author)
        return queryset

    def perform_create(self, serializer):
        author = get_object_or_404(Author, pk=self.kwargs.get('author'))
        serializer.save(author= author)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...