问题描述
在我的 Django Rest Framework
项目中,我有两个模型之间的 ForeignKey
关系:
class Book(models.Model):
...
category = models.ForeignKey(Category,on_delete=models.CASCADE,blank=True,null=True)
...
class Category(models.Model):
name = models.CharField(max_length=100,blank=False)
如您所见,Book
可以属于Category
,但不一定。这意味着“category
”字段可能为空。
因此,在我的 views.py
中,如果用户想要将某个 Book
分配给特定的 Book
,则可以更新/修补任何 Category
实例。 views.py
更新方法如下所示:
class UpdateBooksCategory(generics.GenericAPIView):
'''
Class-based view to update the 'category' field of a Book instance.
'''
serializer_class = BookSerializer
permission_classes = [IsAuthenticated]
def patch(self,request,*args,**kwargs):
# get the Book instance first
book = Book.objects.get(pk=request.data.get('bookId'))
# if it is not assigned to a Category,then assign it
if book and not book.category:
book.category = Category.objects.get(name=request.data.get('categoryName'))
book.save()
serializer = self.get_serializer(book,context={"request": request})
return Response(serializer.data)
# otherwise,return a generic response
return Response({'response': "You have already put the selected Book in a Category."})
如果您能看到,首先我会使用 Book
的 ID 获取用户想要更新的 Book
实例。如果它的 Category
字段尚未填充,我会使用给定的类别名称获取一个 Category
实例并分配它。
为了完整起见,这里是我的序列化器类:
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id','name']
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id',/*some other fields*/,...,'category']
所以,最后我的问题是:我想知道这是否是更新这样的 ForeingKey
字段的首选方式?我的意思是查看基于 UpdateBooksCategory
类的视图,这是正确的做法吗?该代码有效(我使用 PostMan 对其进行了测试),但由于我是 DRF 的新手,所以我想知道这样的更新过程是否正确。
解决方法
您可以更改您的BookSerializer
:
class BookSerializer(serializers.ModelSerializer):
category_id = serializers.IntegerField(write_only=True)
category = CategorySerializer(read_only=True)
class Meta:
model = Book
fields = [
'id',# some other fields,'category','category_id',]
category
将是只读的嵌套数据,然后通过在您的请求中包含 category_id
来设置类别。