Python + Django4 para crear un blog personal (13): actualice la implementación de la página de funciones del artículo

En este artículo, implementamos la última función principal de la gestión de artículos: modificar artículos.

Modificar artículos y crear artículos son en realidad muy similares, hay dos puntos a tener en cuenta:

  • Para modificar un artículo, debe pasar el ID y especificar el artículo que se va a modificar.
  • Para modificar un artículo, primero debe leer el contenido del artículo y luego actualizarlo.

A continuación, implementaremos el código relevante según el modelo MTV.

El modelo del artículo se ha definido anteriormente y no es necesario cambiarlo.

Funciones de vista de escritura

Agregue ariticle/views.pyla función de vista para modificar el artículo article_update():

# 更新文章
def article_update(request, id):
    """
    更新文章的视图函数
    通过POST方法提交表单,更新titile、body字段
    GET方法进入初始表单页面
    id: 文章的 id
    """

    # 获取需要修改的具体文章对象
    article = Article.objects.get(id=id)
    # 判断用户是否为 POST 提交表单数据
    if request.method == "POST":
        # 将提交的数据赋值到表单实例中
        article_post_form = ArticleForm(data=request.POST)
        # 判断提交的数据是否满足模型的要求
        if article_post_form.is_valid():
            # 保存新写入的 title、body 数据并保存
            article.title = request.POST['title']
            article.body = request.POST['body']
            article.save()
            # 完成后返回到修改后的文章中。需传入文章的 id 值
            return redirect("article:article_detail", id=id)
        # 如果数据不合法,返回错误信息
        else:
            return HttpResponse("表单内容有误,请重新填写。")

    # 如果用户 GET 请求获取数据
    else:
        # 创建表单类实例
        article_post_form = ArticleForm()
        # 赋值上下文,将 article 文章对象也传递进去,以便提取旧的内容
        context = { 'article': article, 'article_post_form': article_post_form }
        # 将响应返回到模板中
        return render(request, 'article/update.html', context)

En esta función hacemos lo siguiente:

  • Al solicitar la URL, puede pasar el parámetro id
  • Según los diferentes métodos de solicitud, se implementan las funciones de consultar y actualizar artículos respectivamente.

Escribir plantilla

inputActualizar una plantilla de artículo es casi lo mismo que crear una plantilla de artículo, excepto que pasamos el contenido correspondiente del artículo original en los cuadros de entrada de título y contenido de antemano.

Crea uno nuevo templates/article/update.htmly escribe:

{% extends "base.html" %} {% load static %}
{% block title %} 更新文章 {% endblock title %}
{% block content %}
<div class="container">
    <div class="row">
        <div class="col-12">
            <br>
            <form method="post" action=".">
                {% csrf_token %}
                <div class="form-group">
                    <label for="title">文章标题</label>
                    <!-- 在 value 属性中指定文本框的初始值为旧的内容,即 article 对象中的 title 字段 -->
                    <input type="text" class="form-control" id="title" name="title" value="{
   
   { article.title }}">
                </div>
                <div class="form-group">
                    <label for="body">文章正文</label>
                    <!-- 文本域不需要 value 属性,直接在标签体中嵌入数据即可 -->
                    <textarea type="text" class="form-control" id="body" name="body" rows="12">{
   
   { article.body }}</textarea>
                </div>
                <button type="submit" class="btn btn-primary">完成</button>
            </form>
        </div>
    </div>
</div>
{% endblock content %}

Modificar URL

Configurar el enrutamiento:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', views.hello),
    re_path(r'^$', views.article_list),
    path('list/', views.article_list, name='list'),  # 展示文章
    path('detail/<int:id>/', views.article_detail, name='detail'),  # 文章详情
    path('create/', views.article_create, name='create'),  # 写文章
    path('delete/<int:id>/', views.article_delete, name='delete'),# 删除文章
    # 增加更新文章
    path('update/<int:id>/', views.article_update, name='update'),
]

tempaltes/article/detail.htmlAgregue una entrada para modificar el artículo en la página de detalles del artículo :

...
<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>

Aquí agregamos otro control, solo el autor puede modificar y eliminar sus propios artículos.

Primero modifique nuestro modelo de artículo y cambie el campo de autor a la clave externa del modelo de Usuario:

# 博客文章数据模型
class Article(models.Model):
    # 文章id,主键
    id = models.AutoField(primary_key=True)

    # 文章作者。修改为User的外键,参数 on_delete 用于指定数据删除的方式
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    # 文章标题,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)

Vuelva a migrar el modelo

python manage.py makemigrations article

Luego agregue la verificación del usuario en la plantilla de Detalles.

...
<!-- 写入 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
                <!-- 只有作者可以修改文章 -->
                {% if user == article.author %}
                <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>
                {% endif %}
            </div>
        </div>

Ejecute el servidor:

El error del sistema es el siguiente:

La razón es que el Autor en nuestra tabla de Artículos anterior almacenó el nombre de usuario, pero ahora lo hemos cambiado a la clave externa de Usuario y están relacionados a través de ID.

Por lo tanto, necesitamos cambiar manualmente el valor de Author_id en la tabla de artículos en MySQL a ID de usuario.

Después de la modificación, reinicie el servidor para ver el efecto:

Inicia sesión con otro usuario y compruébalo

Conclusión

Hasta ahora hemos implementado las cuatro funciones principales de agregar, eliminar, modificar y verificar un artículo.

A continuación comenzaremos a aprender la implementación funcional de la gestión de usuarios.

Supongo que te gusta

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