I have two Django models, Discussion and Post set up as follows:
Discussion model:
class Discussion(models.Model):
Discussion_ID = models.AutoField(primary_key=True)
Topic = models.CharField(max_length=50)
Group = models.ForeignKey(Group, related_name="Group_Discussions")
class Meta:
db_table = "Discussions"
Post model:
class Post(models.Model):
Post_ID = models.AutoField(primary_key=True)
Date_Posted = models.DateTimeField(auto_now_add=True)
Discussion = models.ForeignKey(Discussion, db_column="Discussion_ID", related_name="Posts")
User = models.ForeignKey(User, related_name="User_Posts")
Message = models.TextField()
class Meta:
db_table = "Posts"
I want to serialize a list of all discussions, and in the serializer, include ONLY the latest post for each discussion. So far, my serializer looks like this:
class DiscussionSerializer(serializers.ModelSerializer):
last_post = serializers.SerializerMethodField()
post_count = serializers.SerializerMethodField()
class Meta:
model = Discussion
fields = ('Discussion_ID', 'Topic', 'last_post', 'post_count')
def get_last_post(self, obj):
return Post.objects.raw("SELECT * FROM Posts WHERE Discussion_ID = %s ORDER BY Post_ID DESC LIMIT 1" % obj.Discussion_ID)
def get_post_count(self, obj):
return obj.Posts.count()
Unfortunately, this return the following error and I'm not quite sure what else to try:
<RawQuerySet: SELECT * FROM Posts WHERE Discussion_ID = 1 ORDER BY Post_ID DESC LIMIT 1> is not JSON serializable
Basically, I want to serialize the Discussion model along with the lastest post in the discussion into JSON that looks something like this:
{
"Discussion_ID": 1,
"Topic": "Some topic",
"last_post": {
"Post_ID": 1,
"Date_Posted": "...",
"Discussion": 1,
"User": 1,
"Message": "This is a message"
},
"post_count": 10
}
To improve your solution, you might want to move this code to a viewset method and handle some other things like permissions, applying filters for
Posts
(if you have any) and the "not found" error. For example:By the way, this is inspired by DRF's
ModelViewSet
.I managed to get this working with the following:
It feels a bit hacky though so I am still open to other solutions.