Adding a comments feature for a Project in djangorestframework - python

I have created a project API in djangorestframework but I want to add a comments feature in it also. I was scratching my head thinking how can I do it but couldn't end up with a solution since I'm a beginner in djangorestframework.
here is my models.py:
class Project(models.Model):
title = models.CharField(max_length=300)
body = models.TextField(max_length=5000)
header_image = models.ImageField(default="default.jpg")
demo = models.URLField(null=True, blank=True)
code = models.URLField(null=True, blank=True)
and here is my serializers.py:
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = "__all__"
and here is my views.py:
#api_view(["GET"])
def getProjects(request):
project = models.Project.objects.all()
serializer = ProjectSerializer(project, many=True)
return Response(serializer.data)
Please help me in showing how can I add a comments section to the project API
note: I don't want the comments API to be a different object instead it should be a nested object in the object of the project

As each project can have several comments, you should implement Comment model and make a FK between these two
models.py
...
class Comment(models.Model):
project = models.ForeignKey('Project', related_name='comments', on_delete=models.CASCADE)
text = models.TextField(null=False, blank=False)
... # Some other field if you want. like created_time, author, ...
Then you can have a nested serializer to get comments with project:
serializers.py
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('text', ...)
class ProjectSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True)
class Meta:
model = Project
fields = (..., 'comments')

Related

How to use reporting and statistics capabilities for blog post using django

models.py
from django.db import models
from django.contrib.auth.models import User
STATUS = (
(0,"Draft"),
(1,"Publish")
)
class BlogModel(models.Model):
id = models.AutoField(primary_key=True)
blog_title = models.CharField(max_length=200)
blog = models.TextField()
status = models.IntegerField(choices=STATUS, default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"Blog: {self.blog_title}"
class CommentModel(models.Model):
your_name = models.CharField(max_length=20)
comment_text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
blog = models.ForeignKey('BlogModel', on_delete=models.CASCADE)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"Comment by Name: {self.your_name}"
admin.py
from django.contrib import admin
from blog.models import BlogModel,CommentModel
class PostAdmin(admin.ModelAdmin):
list_display = ('blog_title', 'status','created_at','updated_at')
list_filter = ('status',)
search_fields = ('blog_title', 'content',)
admin.site.register(BlogModel, PostAdmin)
admin.site.register(CommentModel)
I created a simple blog post website with comments and I want to create reports and on the admin panel I have to see how to achieve this.
Like how many posts are created and how many have comments and how many post are draft and published
I checked this module but I don't understand how to implement it https://pypi.org/project/django-reports-admin/
You already have most of this, by using PostAdmin. The list_display already shows you how many posts are published/draft, and the change list has filters for that as well.
To show the comment count, simply add that to list_display:
class PostAdmin(admin.ModelAdmin):
list_display = ('blog_title', 'status', 'comment_count', 'created_at', 'updated_at')
def comment_count(self, obj):
return obj.commentmodel_set.count()
comment_count.short_description = 'Comment count'
This thus defines a custom method on the PostAdmin, that displays the comment count as a column, and gives it a user-friendly name as column header.
You can expand this with more statistics if you like. The Django admin is highly customizable.
Note: model names should be in CamelCase, so BlogModel and CommentModel should be Blog and Comment respectively.

Django Rest Framework serializer nested objects internal server error 500

I have three models like those:
class Ambulance(models.Model):
ambulance_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
ambulance_name = models.CharField(max_length=255)
forms = models.ManyToManyField(Form)
class Form(models.Model):
form_id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
form_title = models.CharField(max_length=255)
class Page(models.Model):
page_id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
page_title = models.CharField(max_length=100, default='Untitled Page')
form = models.ForeignKey(
Form,
related_name='pages',
on_delete=models.CASCADE,
null=True
)
And the serializers as follow:
class AmbulanceSerializer(serializers.ModelSerializer):
forms = FormSerializer(read_only=True, many=True)
class Meta:
model = Ambulance
fields = ['ambulance_id', 'ambulance_name', 'forms']
class FormSerializer(ModelSerializer):
pages = PageSerializer(many=True, read_only=True)
class Meta:
model = Form
fields = ['form_id', 'form_title', 'pages']
class PageSerializer(ModelSerializer):
class Meta:
model = Page
fields = '__all__'
They were working and give me the nested object that I wanted but after adding many-to-many relationships, it gives me an internal server error 500 and it didn't tell me what the problem was, after debugging I found the problem occurs when calling AmbulanceSerializer(ambulance) or FormSerializer(form)
Could someone give me some hint? and what the problem actually!
Your code is wrong:
Can you please check this line?
fields = fields = ['ambulance_id', 'ambulance_name', 'forms']
which is wrong syntax.
You can try with this:
fields = ['ambulance_id', 'ambulance_name', 'forms']
Following your comment, where you state that you are using these serializers for "all types of requests", the answer is simple: remove read_only=True whenever you are using a nested serializer.
The read_only parameter will stop writes i.e. POST, PUT, etc... requests.

Django Rest Framework - CreateAPIView ForeignKey lookup fields

I am using Django Rest Framework CreateAPIView in order to create a comment. So far everything is OK and here is my code.
Models
class Posts(models.Model):
title = models.CharField(max_length=512, null=True)
slug = models.CharField(max_length=512, null=True)
class Comments(models.Model):
post = models.ForeignKey(Posts, on_delete=models.CASCADE)
content = models.CharField(max_length=5000, null=True)
Serializer
class CommentCreateSerializer(ModelSerializer):
class Meta:
model = Comments
fields = [
'content',
'post'
]
and view
class CommentCreateView(CreateAPIView):
permission_classes = [IsAuthenticated]
queryset = Comments.objects.all()
serializer_class = CommentCreateSerializer
I sent a post request to the create route with post(ID) and content and everything worked. But the problem is I wanna pass post slug instead of post ID.
I am not sure how can I do that. I am familiar with lookup_fields but I am not certain how to apply them for ForeignKey match.
You can use SlugRelatedField in CommentCreateSerializer to use slug instead of pk when you pass the post value on Comment Create request, like this:
class CommentCreateSerializer(ModelSerializer):
post = serializers.SlugRelatedField(
queryset=Posts.objects.all(), slug_field='slug'
)
class Meta:
model = Comments
fields = [
'content',
'post'
]
In the CommentAPIview you need to overwrite the perform create method in to the lookup like so
def perform_create(self):
post_pk = self.kwargs.get("post_pk")
post = get_object_or_404(Post, pk=post_pk)
serializer.save(post=post)

storing a List using Django REST framework

I have a model that contains the newly added ListField class in DRF.
I am trying to store a List of strings so the output would look like so:
{
"hashtags":["something", "new"],
}
I'm pretty new to working with DRF but I seem to be having some trouble serializing the result. When I run the request I received a
HashField() is not JSON serializable error. Again I'm new to working with the the framework and Python in general but any suggestions, point in the right direction would be a help.
models.py
class HashField(serializers.ListField):
child = serializers.CharField(max_length=100)
class Mention(models.Model):
author = models.ForeignKey(User)
hashtags = HashField()
placename = models.CharField(max_length=140, default='SOME STRING')
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.placename
serializers.py
class MentionSerializer(serializers.ModelSerializer):
class Meta:
model = Mention
Django REST Framework has different kind of serializers, what you need here is a field serializer that validates a list type.
in serializers.py do as follow:
class MentionSerializer(serializers.ModelSerializer):
hashtags = serializers.ListField()
class Meta:
model = Mention

How can I create Django ModelForm for an abstract Model?

I have an abstract model that all my other models inherit from, it looks like this.
class SupremeModel(models.Model):
creator = models.ForeignKey(User, related_name="%(class)s_creator")
created = models.DateTimeField(null=True, blank=True)
deleted = models.BooleanField(default=False)
modified = models.DateTimeField(null=True,blank=True)
class Meta:
abstract = True
I then have a bunch of other models that inherit from this model, with something along these lines...
class ExampleModel(SupremeModel):
name = models.TextField(null=False, blank=False)
description = models.TextField(null=False, blank=False)
class AnotherModel(SupremeModel):
title = models.TextField(null=False, blank=False)
location = models.TextField(null=False, blank=False)
I want to create a Django model form for nearly all of my custom models that look similar to ExampleModel, but I always want the fields in SupremeModel to be excluded in the form...
How can I create a ModelForm that can be used to inherit the exclude parameters that will hide creator,created,deleted, and modified but show all of the other fields (in this case name and description or title and location).
you may try this
class ExcludedModelForm(ModelForm):
class Meta:
exclude = ['creator', 'created', 'deleted', 'modified']
class ExampleModelForm(ExcludedModelForm):
class Meta(ExcludedModelForm.Meta):
model = ExampleModel

Categories

Resources