在Django Rest Framework中发布外键关系 [英] Posting a foreign key relationship in Django Rest Framework
问题描述
在我的模型中,我有以下课程:
In my models, I have the following classes:
class Topic(models.Model):
name = models.CharField(max_length=25, unique=True)
class Content(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
topic = models.ForeignKey(Topic, blank=True, null=True)
我的序列化器是这样的:
class TopicSerializer(serializers.ModelSerializer):
class Meta:
model = Topic
fields = ('name')
class ContentSerializer(serializers.ModelSerializer):
topic = TopicSerializer(read_only=True)
class Meta:
model = Content
fields = ('title', 'body', 'topic')
好的,因此在我的 urls 文件中,我具有以下模式:
Alright, so in my urls file, I have the following pattern:
urlpatterns = [
...
url(r'^api/topic_detail/(?P<name>[a-zA-Z0-9-]+)/content_list/$', views.topic_content_list, name='topic_content_list'),
...
]
因此,当用户说/api/topic_detail/sports/content_list/
时,我们将获得所有主题为 sports 的内容的列表.现在我想要的是,如果我们将以下数据 POST 发布到上述URL,那么将创建一个Content对象,其中的主题字段会自动与体育相关.
Therefore, when the user goes to say /api/topic_detail/sports/content_list/
, we get a list of all the contents that has the topic of sports. Now what I want is if we POST the following data to the above URL, then a Content object is created with the topic field related automatically to sports.
我正尝试在我的视图中以以下方式执行此操作:
I am trying to do this the following way in my views:
@api_view(['GET', 'POST'])
def topic_content_list(request, name):
try:
topic = Topic.objects.get(name=name)
except:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
contents = Content.objects.filter(topic=topic)
serializer = ContentSerializer(contents, many=True)
return Response(serializer.data)
elif request.method == 'POST':
request.data["topic"] = topic
serializer = ContentSerializer(data=request.data)
print request.data
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
现在可以说我进入URL /api/topic_detail/sports/content_list/
并将其发布:
Now lets say I go the URL /api/topic_detail/sports/content_list/
and POST this:
{
"title": "My blog post",
"body" : ".....",
}
将创建内容对象,并且正确设置了标题和正文字段.但是,主题字段设置为null.我怎样才能解决这个问题?感谢您的帮助.
The content object gets created and the title and body field is set properly. However, the topic field is set to null. How can I fix this? Any help is appreciated.
另外,请不要建议使用通用视图集,因为我对这么多自动发生的事情感到不舒服.
Also, please don't suggest using generic viewsets, as I am uncomfortable with so many things happening automatically.
编辑
好的,所以我纠正了我的愚蠢错误:
Alright, so I fixed my dumb mistake :
class ContentSerializer(serializers.ModelSerializer):
topic = TopicSerializer(read_only=False)
class Meta:
model = Content
fields = ('title', 'body', 'topic')
也就是说,我将read_only参数设置为False.但是,现在该帖子创建了一个新错误:
That is, I set the read_only argument to False. However, now the post creates a new error:
{
"topic": {
"non_field_errors": [
"Invalid data. Expected a dictionary, but got Topic."
]
}
}
我敢肯定,这是指我要发送的data.website不是JSON,而是一个Django模型实例.如何对单个实例进行JSON化?
This I am pretty sure refers to the fact that the data.website I'm sending in is not JSON, but instead just a Django model instance. How can I JSONify the single instance?
推荐答案
这是来自您的序列化器.
This is from your serializer.
topic = TopicSerializer(read_only=True)
这意味着您的主题是只读的,因此当您尝试保存序列化程序时,不会保存主题.删除它,问题将得到解决.
It means your topic is read only so when you are trying to save your serializer, topic is not getting saved. Remove that and problem would be fixed.
现在,根据第二个错误,这是因为它期待一个dict,并且您正在传递模型实例,所以有两个选择.要么手动创建字典.
Now as per the second error, it is because it is expecting a dict and you are passing the model instance, so you have two options. Either create the dict by hand.
topic_dict = {"name":topic.name}
并在request.data中将其作为主题"传递,然后保存或提供topic_id,因为存在外键关系,它应该可以工作.
and pass that as 'topic' in request.data and then save or give the topic_id, as there is a foreign key relationship, it should work.
所以会是这样:
request.data["topic_id"] = topic.id
现在,您选择要做的完全由您决定.
Now what you choose to do is totally upto you.
这篇关于在Django Rest Framework中发布外键关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!