0

I'm absolutely new to Django and for some reason, I had to jump right to Django REST framework. I want to save JSON objects sent as POST requests in my database. The JSON object looks like this:

[{
    "title": "Bitcoin Price Likely to Reach $50K 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 $48,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"
}]

I created my models like this:

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

serializers:

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"]

and finally my view:

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)

Normally i try to not to post vague and general questions, but in this one, i've got absolutely no idea how to debug and find the problem here. The only thing that i get from terminal is

Bad Request: /news/

could you please point out the problem, and also give a solution on how to fix it?

Danial
  • 362
  • 4
  • 18

2 Answers2

1

Let me help try to help you out with this problem.

In current state, the solution will be to override the create method of the NewsSerializer to create the news and keyword instances.

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

Also I would update the post method of view as follow:

...
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)
...
VJ Magar
  • 974
  • 7
  • 14
0

ok, there might be a validation error.

description is required in the model and you are passing empty. >> "description": "",

      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

Read https://www.django-rest-framework.org/api-guide/validators/#validation-in-rest-framework

rahul.m
  • 5,572
  • 3
  • 23
  • 50
  • Fixed this one also, but still, all I get is `Bad Request: /news/` error. can't Django show a more precise and informative error? if so, how can I enable that? Thank you very much. – Danial Feb 09 '21 at 10:13
  • refer this https://stackoverflow.com/questions/19875789/django-gives-bad-request-400-when-debug-false – rahul.m Feb 09 '21 at 10:28