`.create()` 方法默认不支持可写点源字段。为序列化程序编写一个显式的 `.create()` 方法

时间:2021-04-14 11:07:09

标签: django django-rest-framework django-serializer

我正在尝试在我的借阅视图中启用 post 方法以启用管理员、从当前用户中选择以及从可用书籍中进行选择。

serializers.py
class BookListSerializer(serializers.ModelSerializer):
    authors = serializers.SlugRelatedField(many = True, queryset = models.Author.objects.all(),slug_field = 'name',) #To represent the relationship as a string instead of id
    genre = serializers.SlugRelatedField(many = True,queryset = models.Genre.objects.all(),slug_field = 'name')


class Meta:
    model = models.Book
    fields = ('name','authors','rating', 'genre')

class BorrowedSerializer(serializers.ModelSerializer):
    who_borrowed = serializers.PrimaryKeyRelatedField(queryset = get_user_model().objects.all() ,source = 'who_borrowed.username',)
name = serializers.PrimaryKeyRelatedField(queryset = models.Book.objects.all(),
                                         source = 'name.name',)

#borrowed_date = serializers.DateTimeField(format = "%H:%M, %d-%m-%Y")
#returned_date = serializers.DateTimeField(format = "%H:%M, %d-%m-%Y" )

class Meta:
    model = models.Borrowed
    fields = ('who_borrowed','name','has_returned','borrowed_date','returned_date',)

然后是我的模型

models.py

class Book(models.Model):
name = models.CharField(max_length = 150,)   #Name of books
authors = models.ManyToManyField(Author,)     
genre = models.ManyToManyField(Genre)       
publisher = models.ForeignKey(Publisher, on_delete = models.SET_DEFAULT, default = '2') 
#A book should have a publisher will include a none field for books without publishers

pub_date = models.DateField()
price = models.DecimalField(max_digits = 10, decimal_places = 2) 
isbn = models.CharField(max_length = 13, unique = True, null = True, blank = True,
                        validators = [MinLengthValidator(13)]) 


class Borrowed(models.Model):    #Model for users borrowing and returning
name = models.ForeignKey(Book, on_delete = models.CASCADE,) #Consider making one to many field
borrowed_date = models.DateTimeField(auto_now_add = True, )   #Date is created as soon as instance is created
has_returned = models.BooleanField(default = False)    #Field that determines if a model is returend or not
returned_date = models.DateTimeField(null = True, blank = True,)    #Date that changes as soon as book is returned
who_borrowed = models.ForeignKey(get_user_model(), on_delete = models.SET_DEFAULT, default ='9c495b90-3900-43d1-875d-6b15d5d5ab55')

Django 可浏览 api 显示可供选择的书籍和用户借书的方式,但当我想发布请求时,它会显示标题中的错误。 我不知道如何创建一个允许显示这些选项并允许发布或放置请求的创建方法。

简而言之,如果我删除源参数,一切正常,但我希望显示的数据不是 Id 或 UUID,而是用户名和书名。

2 个答案:

答案 0 :(得分:0)

您可以参考DRF- doc

在您的情况下,以下更改应该足够了。

class BorrowedSerializer(serializers.ModelSerializer):
    who_borrowed = serializers.PrimaryKeyRelatedField(queryset = get_user_model().objects.all() ,source = 'who_borrowed.username',)
    name = serializers.PrimaryKeyRelatedField(queryset = models.Book.objects.all(),
                                         source = 'name.name',)

    class Meta:
        model = models.Borrowed
        fields = ('who_borrowed','name','has_returned','borrowed_date','returned_date',)

    def create(self, validated_data):
        return models.Borrowed.objects.create(**validated_data)
        # or 
        # return super(BorrowedSerializer, self).create(validated_data)

答案 1 :(得分:0)

class BorrowedSerializer(serializers.ModelSerializer):
who_borrowed = serializers.SlugRelatedField(queryset = get_user_model().objects.all(),slug_field = 'username')
name = serializers.SlugRelatedField(queryset = models.Book.objects.all(), slug_field = 'name')

将“PrimaryKeyRelatedFields”更改为“SlugRelatedFields”也对我有用。