使用 Django REST 框架序列化程序将 JSON 请求保存到数据库
Use Django REST framework serializer to save JSON requests to database
我对 Django 完全陌生,出于某种原因,我不得不直接跳到 Django REST 框架。
我想在我的数据库中保存作为 POST 请求发送的 JSON 个对象。
JSON 对象如下所示:
[{
"title": "Bitcoin Price Likely to Reach K Soon According to This Indicator",
"description": "",
"date": "2021-02-09T09:08:58Z",
"link": "https://cryptopotato.com/bitcoin-price-likely-to-reach-50k-soon-according-to-this-indicator/",
"keywords": [{
"name": "bitcoin"
}],
"source": "https://cryptocompare.com"
},
{
"title": "Post-Tesla News FOMO Helps Bitcoin Price to Surge Above ,000",
"description": "",
"date": "2021-02-09T09:08:58Z",
"link": "https://www.cryptoglobe.com/latest/2021/02/post-tesla-news-fomo-helps-bitcoin-price-to-surge-above-48000/",
"keywords": [{
"name": "bitcoin"
}],
"source": "https://cryptocompare.com"
}]
我是这样创建模型的:
class Keywords(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class News(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
date = models.DateTimeField()
link = models.URLField()
keywords = models.ManyToManyField(Keywords)
source = models.CharField(max_length=30)
class Meta:
db_table = "News"
# ordering = "-date"
def __str__(self):
return self.title
序列化程序:
class KeywordSerializer(serializers.ModelSerializer):
class Meta:
model = Keywords
fields = ["name"]
class NewsSerializer(serializers.ModelSerializer):
keywords = KeywordSerializer(read_only=True, many=True)
class Meta:
model = News
fields = ["title", "description", "date", "link", "keywords", "source"]
最后是我的观点:
class NewsView(APIView):
def post(self, request):
news_serializer = NewsSerializer(data=request.data, many=True)
try:
if news_serializer.is_valid():
news_serializer.save()
return Response("Created successfully", status=status.HTTP_201_CREATED)
except Exception as e:
print(e)
return Response("Error, Don't know what", status=status.HTTP_400_BAD_REQUEST)
通常我尽量不 post 模糊和笼统的问题,但在这个问题中,我完全不知道如何调试和找到问题所在。我从终端得到的唯一东西是
Bad Request: /news/
能否指出问题所在,并给出解决方法?
好的,可能存在验证错误。
模型中需要 描述,而您传递的是空的。 >> "描述": "",
try:
if news_serializer.is_valid():
news_serializer.save()
return Response("Created successfully", status=status.HTTP_201_CREATED)
else:
print(news_serializer.errors)
return Response('Invalid data') # whatever you want
阅读https://www.django-rest-framework.org/api-guide/validators/#validation-in-rest-framework
让我来帮助您解决这个问题。
在当前状态下,解决方案是覆盖 NewsSerializer
的 create
方法来创建新闻和关键字实例。
class NewsSerializer(serializers.ModelSerializer):
...
def create(self, validated_data):
keywords = validated_data.pop("keywords", None)
news, _ = News.objects.get_or_create(**validated_data)
if news:
for keyword in keywords:
keyword, _ = Keywords.objects.get_or_create(**keyword)
news.keywords.add(key)
return news
另外我会更新 post 视图方法如下:
...
def post(self, request):
for news in request.data:
serializer = NewsSerializer(news)
serializer.save(raise_exception=True)
return Response("Created successfully", status=status.HTTP_201_CREATED)
...
我对 Django 完全陌生,出于某种原因,我不得不直接跳到 Django REST 框架。 我想在我的数据库中保存作为 POST 请求发送的 JSON 个对象。 JSON 对象如下所示:
[{
"title": "Bitcoin Price Likely to Reach K Soon According to This Indicator",
"description": "",
"date": "2021-02-09T09:08:58Z",
"link": "https://cryptopotato.com/bitcoin-price-likely-to-reach-50k-soon-according-to-this-indicator/",
"keywords": [{
"name": "bitcoin"
}],
"source": "https://cryptocompare.com"
},
{
"title": "Post-Tesla News FOMO Helps Bitcoin Price to Surge Above ,000",
"description": "",
"date": "2021-02-09T09:08:58Z",
"link": "https://www.cryptoglobe.com/latest/2021/02/post-tesla-news-fomo-helps-bitcoin-price-to-surge-above-48000/",
"keywords": [{
"name": "bitcoin"
}],
"source": "https://cryptocompare.com"
}]
我是这样创建模型的:
class Keywords(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class News(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
date = models.DateTimeField()
link = models.URLField()
keywords = models.ManyToManyField(Keywords)
source = models.CharField(max_length=30)
class Meta:
db_table = "News"
# ordering = "-date"
def __str__(self):
return self.title
序列化程序:
class KeywordSerializer(serializers.ModelSerializer):
class Meta:
model = Keywords
fields = ["name"]
class NewsSerializer(serializers.ModelSerializer):
keywords = KeywordSerializer(read_only=True, many=True)
class Meta:
model = News
fields = ["title", "description", "date", "link", "keywords", "source"]
最后是我的观点:
class NewsView(APIView):
def post(self, request):
news_serializer = NewsSerializer(data=request.data, many=True)
try:
if news_serializer.is_valid():
news_serializer.save()
return Response("Created successfully", status=status.HTTP_201_CREATED)
except Exception as e:
print(e)
return Response("Error, Don't know what", status=status.HTTP_400_BAD_REQUEST)
通常我尽量不 post 模糊和笼统的问题,但在这个问题中,我完全不知道如何调试和找到问题所在。我从终端得到的唯一东西是
Bad Request: /news/
能否指出问题所在,并给出解决方法?
好的,可能存在验证错误。
模型中需要描述,而您传递的是空的。 >> "描述": "",
try:
if news_serializer.is_valid():
news_serializer.save()
return Response("Created successfully", status=status.HTTP_201_CREATED)
else:
print(news_serializer.errors)
return Response('Invalid data') # whatever you want
阅读https://www.django-rest-framework.org/api-guide/validators/#validation-in-rest-framework
让我来帮助您解决这个问题。
在当前状态下,解决方案是覆盖 NewsSerializer
的 create
方法来创建新闻和关键字实例。
class NewsSerializer(serializers.ModelSerializer):
...
def create(self, validated_data):
keywords = validated_data.pop("keywords", None)
news, _ = News.objects.get_or_create(**validated_data)
if news:
for keyword in keywords:
keyword, _ = Keywords.objects.get_or_create(**keyword)
news.keywords.add(key)
return news
另外我会更新 post 视图方法如下:
...
def post(self, request):
for news in request.data:
serializer = NewsSerializer(news)
serializer.save(raise_exception=True)
return Response("Created successfully", status=status.HTTP_201_CREATED)
...