Error in formatting: AttributeError: 'JsonResponse' object has no attribute '_headers'

2.1k Views Asked by At

I am building an app using Django and JavaScript. In Java I have a function that looks like this:

fetch('/posts')
.then(response => response.json())
.then(posts => {

The first line of the JavaScript code actually calls the "post_list" function in my .views

from django.contrib.auth.decorators import login_required
from django.http import JsonResponse

from .models import Post

@login_required
def post_list(request):
    posts = Post.objects.filter(username=request.user)
    posts = posts.order_by("-timestamp").all()
    return JsonResponse([p.serialize() for p in posts], safe=False)

But then the program crashes in the last line (when I try to return a JsonResponse) and I get a 500 Internal Server Error. As a result I don get a response and my JavaScript .then(response ..... line does not run.

I am not sure If this is relevant to answer the question, but My model looks like this:

from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()

class Post(models.Model):
    username = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user")
    post = models.CharField(max_length=365)
    like = models.PositiveIntegerField(default=0)
    timestamp = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return f"{self.username} posted {self.post} the {self.timestamp}, and the post has {self.like} likes"
        
    def serialize(self):
        return {
            "id": self.id,
            "username":self.username,
            "post": self.post,
            "like": self.like,
            "timestamp": self.timestamp.strftime("%b %d %Y, %I:%M %p"),
        }

So, does anyone know why I'm getting a 500 Internal server error?

1

There are 1 best solutions below

1
On

You should not be seeing this error if you import JsonResponse from the correct location. Instead, you should be getting an error "User object is not JSON serializable", which you can fix by doing something like this:

# models.py
from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()


class Post(models.Model):
    username = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user")
    post = models.CharField(max_length=365)
    like = models.PositiveIntegerField(default=0)
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.username} posted {self.post} at {self.timestamp}, and the post has {self.like} likes"

    def serialize(self):
        return {
            "id": self.id,
            "username": {
                "username": self.username.username,
                "displayName": self.username.get_full_name(),
                "lastLogin": str(self.username.last_login.replace(microsecond=0)),
            },
            "post": self.post,
            "like": self.like,
            "timestamp": self.timestamp.strftime("%b %d %Y, %I:%M %p"),
        }

As some additional advice:

  • Don't call a user object a username: it becomes confusing when you don't get a username but a full user object
  • Javascript is fully capable of rendering date formats in a way that make sense to the visitor, so it's preferable to transmit datetimes as ISO-8601 format, which both python and Javascript can handle. I've added that as example for the lastLogin attribute on the user serialization.