如何在Django中实现关联单篇博客的评论提交API
Hey there! Let's get your comment submission API properly linked to your BlogPost entries. Here's a step-by-step breakdown of what you need to do:
1. First, Define (or Update) Your Comment Model
You didn't include your Comment model code, so let's start by making sure it has a foreign key relationship to BlogPost—this is the core link between comments and their parent blog posts:
from django.db import models from .models import BlogPost # Adjust the import path to match your app structure class Comment(models.Model): # Foreign key to associate the comment with a specific BlogPost blog_post = models.ForeignKey( BlogPost, on_delete=models.CASCADE, related_name='comments' # Lets you access comments via `blog_post.comments` later ) name = models.CharField(max_length=100) email = models.EmailField() subject = models.CharField(max_length=255) comment = models.TextField() created_at = models.DateTimeField(auto_now_add=True) # Optional: track comment submission time def __str__(self): return f"Comment by {self.name} on {self.blog_post.description}"
Note: The
related_name='comments'replaces your manual@property commentsin theBlogPostmodel. Django automatically creates this reverse relationship, so you can safely delete that property from yourBlogPostclass.
2. Update Your URL Configuration
For a RESTful approach, your comment creation endpoint should be nested under the target blog post. Add this to your app's urls.py:
from django.urls import path from .views import CommentCreateAPIView urlpatterns = [ # ... your existing URLs path('blogs/<int:blog_id>/comments/', CommentCreateAPIView.as_view(), name='create-comment'), ]
Now, when a user sends a POST request to /api/blogs/123/comments/, we know they're adding a comment to the blog post with ID 123.
3. Modify the CommentCreateAPIView to Link the BlogPost
Update your view to grab the blog_id from the URL, fetch the corresponding BlogPost, and attach it to the comment before saving:
from rest_framework.generics import CreateAPIView from django.shortcuts import get_object_or_404 from .models import Comment, BlogPost from .serializers import CommentPostSerializer class CommentCreateAPIView(CreateAPIView): queryset = Comment.objects.all() serializer_class = CommentPostSerializer def perform_create(self, serializer): # Fetch the blog post using the ID from the URL, return 404 if it doesn't exist blog_post = get_object_or_404(BlogPost, pk=self.kwargs['blog_id']) # Save the comment with the linked blog post serializer.save(blog_post=blog_post)
Using get_object_or_404 ensures that if the requested blog_id is invalid, the API returns a clear 404 Not Found response instead of a generic server error.
4. Keep Your Serializer (or Adjust for Request Body Input)
Your existing CommentPostSerializer works perfectly for the URL-based approach, since we handle the blog_post association in the view. If you prefer to let clients send the blog_post_id directly in the request body instead, update the serializer like this:
from rest_framework import serializers from .models import Comment, BlogPost class CommentPostSerializer(serializers.ModelSerializer): # Add this field to accept a BlogPost ID from the request body blog_post = serializers.PrimaryKeyRelatedField(queryset=BlogPost.objects.all()) class Meta: model = Comment fields = ['name', 'email', 'subject', 'comment', 'blog_post']
With this setup, clients would send a POST body like:
{ "name": "John Doe", "email": "john@example.com", "subject": "Great Post!", "comment": "Loved your travel tips!", "blog_post": 123 }
Testing the API
Send a POST request to your configured endpoint (e.g., /api/blogs/<your-blog-id>/comments/) with the required fields (name, email, subject, comment). The comment will automatically be linked to the specified blog post, and you can retrieve it via your BlogPostSerializer which already includes the comments field.
内容的提问来源于stack exchange,提问作者saroj paudel




