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_ZONE
a 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 .
article
es el articulo que se esta comentandouser
es 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 Django
ló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.py
URL 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 500
y get_object_or_404()
se devolverá el error 404. Por el contrario, devolver un error 404 es más preciso.
redirect():
Regresar a un url
medio 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, Model
se llamará automáticamente al método Model
de este objeto get_absolute_url()
. Por lo tanto, el modelo será modificado inmediatamente article
.
Modificar modelo de artículo
article/models.py
Agregar 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.py
es 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>
 
<a>{
{ article.created|date:'Y-m-d H:i:s' }}</a>
 
<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>
 
<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.count
es 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>
reemplazardiv
e 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.