Python + Django4 para crear un blog personal (16): implementación de la función de comentario de artículo

En el artículo anterior, implementamos la función de registro de usuarios y ahora se ha completado el módulo de gestión de usuarios.

A continuación, implementemos otra función importante del blog: los comentarios de artículos.

Con la acumulación de conocimientos sobre la gestión de artículos, es más fácil implementar la función de gestión de comentarios.

Escribe los módulos correspondientes según el modelo MTV.

Crear aplicación

Crea una nueva App para la gestión de comentarios a través del siguiente código:

python manage.py startapp comment

Registrar aplicación

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'article',
    'userprofile',
    # 新增'comment'代码,激活app
    'comment',
]

Para mostrar que la hora en que se publicó el comentario es la hora de China, modifique la configuración de la zona horaria TIME_ZONEa la zona horaria de Shanghai.

TIME_ZONE = 'Asia/Shanghái'

Definir modelo

from django.db import models
from django.contrib.auth.models import User
from article.models import Article

# 博文的评论
class Comment(models.Model):
    article = models.ForeignKey(Article,
        on_delete=models.CASCADE,
        related_name='comments'
    )
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='comments'
    )
    body = models.TextField()
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('created',)

    def __str__(self):
        return self.body[:20]

En el modelo definimos dos claves foráneas.

Si una clave común es la clave principal en una relación, entonces la clave común se denomina clave externa en otra relación .

  • articlees el articulo que se esta comentando
  • useres el editor del comentario

Migrar datos

Crear formulario

Crear un nuevo formulario de comentarios

from django import forms
from .models import Comment

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ['body']

En la tabla de comentarios, hay dos campos que pertenecen a claves externas. Para los campos de clave externa, la Djangológica interna se puede generar automáticamente en asociación con la tabla de datos externos.

En realidad, sólo necesitamos los campos de procesamiento de primer plano en el formulario body.

Crear RRL

Agregar django4blog/urls.pyURL de administración de comentarios:

from django.contrib import admin
from django.urls import path, re_path
# 引入app视图
import article.views
import userprofile.views
import comment.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', article.views.hello),
    re_path(r'^$', article.views.article_list),
    path('list/', article.views.article_list, name='list'),  # 展示文章
    path('detail/<int:id>/', article.views.article_detail, name='detail'),  # 文章详情
    path('create/', article.views.article_create, name='create'),  # 写文章
    path('delete/<int:id>/', article.views.article_delete, name='delete'),# 删除文章
    path('update/<int:id>/', article.views.article_update, name='update'),    # 更新文章
    path('login/', userprofile.views.user_login, name='login' ),
    path('logout/', userprofile.views.user_logout, name='logout' ),
    path('register/', userprofile.views.user_register, name='register' ),
    # 增加评论管理
    path('post-comment/<int:article_id>/', comment.views.post_comment, name='post_comment' ),
]

Crear vista

La función de vista comentada es la siguiente:

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse

from article.models import Article
from .forms import CommentForm

# 文章评论
@login_required(login_url='/login/')
def post_comment(request, article_id):
    article = get_object_or_404(Article, id=article_id)
    # 处理 POST 请求
    if request.method == 'POST':
        comment_form = CommentForm(request.POST)
        if comment_form.is_valid():
            new_comment = comment_form.save(commit=False)
            new_comment.article = article
            new_comment.user = request.user
            new_comment.save()
            return redirect(article)
        else:
            return HttpResponse("表单内容有误,请重新填写。")
    # 处理错误请求
    else:
        return HttpResponse("发表评论仅接受POST请求。")

get_object_or_404():Tiene Model.objects.get()básicamente la misma funcionalidad que . La diferencia es que en un entorno de producción, si el usuario solicita un objeto que no existe, Model.objects.get()se devolverá (error interno del servidor) Error 500y get_object_or_404()se devolverá el error 404. Por el contrario, devolver un error 404 es más preciso.

redirect():Regresar a un urlmedio apropiado: es decir, después de que el usuario envía un comentario, es redirigido a la página de detalles del artículo. Cuando su parámetro es un objeto, Modelse llamará automáticamente al método Modelde este objeto get_absolute_url(). Por lo tanto, el modelo será modificado inmediatamente article.

Modificar modelo de artículo

article/models.pyAgregar get_absolute_url()método al modelo de artículo :

# 博客文章数据模型
class Article(models.Model):
    # 文章id,主键
    id = models.AutoField(primary_key=True)
    # 文章作者
    author = models.CharField(max_length=100)
    # 文章标题,models.CharField 为字符串字段,用于保存较短的字符串,比如标题
    title = models.CharField('标题',max_length=100)

    # 文章正文,保存大量文本使用 TextField
    body = models.TextField('文章正文')

    # 文章创建时间,参数 default=timezone.now 指定其在创建数据时将默认写入当前的时间
    created = models.DateTimeField(default=timezone.now)

    # 文章更新时间,参数 auto_now=True 指定每次数据更新时自动写入当前时间
    updated = models.DateTimeField(auto_now=True)
    # 获取文章地址
    def get_absolute_url(self):
        return reverse('detail', args=[self.id])

reverse()La redirección de ruta se implementa devolviendo la URL de la página de detalles del artículo a través del método.

Modificar la vista de detalles del artículo

El módulo de comentarios debe mostrarse en la página de detalles del artículo, por lo que el contexto del módulo de comentarios también debe pasarse a la plantilla.

Por tanto la modificación article/views.pyes article_detail():

# 文章详情
def article_detail(request,id):
    # 取出相应的文章
    article = Article.objects.get(id=id)
    # 取出文章评论
    comments = Comment.objects.filter(article=id)
    # 需要传递给模板的对象
    context = {'article': article, 'comments': comments}
    # 载入模板,并返回context对象
    return render(request, 'article/detail.html', context)

Modificar plantilla de detalles del artículo

<!-- extends表明此页面继承自 base.html 文件 -->
{% extends "base.html" %}
{% load static %}

<!-- 写入 base.html 中定义的 title -->
{% block title %}
    文章详情
{% endblock title %}

<!-- 写入 base.html 中定义的 content -->
{% block content %}

    <!-- 文章详情 -->
    <div class="container">
        <!--    <div class="row">-->
        <!-- 标题及作者 -->
        <h1 class="col-12 mt-4 mb-4">{
   
   { article.title }}</h1>
        <div class="col-12 alert alert-primary">
            <div class="col-12">
                <a>作者:{
   
   { article.author }}</a>
                &nbsp
                <a>{
   
   { article.created|date:'Y-m-d H:i:s' }}</a>
                &nbsp
                <a href="#" data-bs-toggle="modal" data-bs-target="#myModal">删除文章</a>
                <!-- 新增一个隐藏的表单 -->
                <form
                        style="display:none;"
                        id="safe_delete"
                        action="{% url "delete" article.id %}"
                        method="POST"
                >
                    {% csrf_token %}
                    <button type="submit">发送</button>
                </form>
                &nbsp
                <a href="{% url "update" article.id %}">编辑文章</a>
            </div>
        </div>
        <!-- 文章正文 -->
        <div class="col-12">
            <p>{
   
   { article.body }}</p>
        </div>
        <!--    </div>-->
    <div class="container">
    <div class="col-12">
        <!-- 发表评论 -->
        <hr>
        {% if user.is_authenticated %}
            <div>
                <form
                        action="{% url "post_comment" article.id %}"
                        method="POST"
                >
                    {% csrf_token %}
                    <div class="form-group">
                        <label for="body">
                            <strong>
                                我也要发言:
                            </strong>
                        </label>
                        <textarea
                                type="text"
                                class="form-control"
                                id="body"
                                name="body"
                                rows="2"></textarea>
                    </div>
                    <br>
                    <!-- 提交按钮 -->
                    <button type="submit" class="btn btn-primary ">发送</button>
                </form>
            </div>
            <br>
        {% else %}
            <br>
            <h5 class="col-12 ">
                请<a href="{% url 'login' %}">登录</a>后回复
            </h5>
            </h5>
            <br>
        {% endif %}
    </div>
    </div>
        <!-- 显示评论 -->
        <h4>共有{
   
   { comments.count }}条评论</h4>
        <div>
            {% for comment in comments %}
                <hr>
                <p>
                    <strong style="color: pink">
                        {
   
   { comment.user }}
                    </strong> 于
                    <span style="color: green">
                    {
   
   { comment.created|date:"Y-m-d H:i:s" }}
                </span> 时说:
                </p>
                <pre style="font-family: inherit; font-size: 1em;">
                {
   
   { comment.body }}</pre>
            {% endfor %}
        </div>
    </div>
    </div>

{% endblock content %}
  • action¿ A qué URL se deben enviar los datos especificados en el componente del formulario ?
  • Lo que se muestra en el comentario comments.countes el método integrado en el objeto de plantilla para contar los elementos contenidos.
  • |date:"Y-m-d H:i :s":Ya está familiarizado con el carácter de barra vertical, que se utiliza para "pegar" ciertas propiedades o funciones en un objeto. Esto se utiliza para formatear cómo se muestran las fechas.
  • <pre>Al definir texto preformateado, la función más crítica en nuestro proyecto es preservar espacios y nuevas líneas. Esta etiqueta cambiará la fuente, el tamaño, etc. del texto, así que utilice el atributo de estilo para redefinir el contenido relevante. Intente <pre>reemplazar dive ingrese varias líneas de texto para probar el efecto.

Ejecutar pruebas

Después de ejecutar, verifique la página de detalles. Si no ha iniciado sesión, se le pedirá que inicie sesión para responder al comentario.

Inicia sesión para publicar un comentario

Conclusión

Hasta ahora hemos completado las funciones principales de gestión, publicación y visualización de comentarios, de hecho, algunos sitios web también ofrecen la función de modificar y eliminar comentarios.

El proceso de implementación es similar a la modificación y eliminación de artículos, usted mismo puede completar el desarrollo relevante.

Los módulos funcionales principales de nuestro sitio web de blog, incluidos artículos, usuarios y comentarios, están básicamente completos.

A continuación completaremos algunos pequeños puntos funcionales prácticos del blog.

Por ejemplo, paginación, clasificación y búsqueda, etc.

Supongo que te gusta

Origin blog.csdn.net/agelee/article/details/127211000
Recomendado
Clasificación