You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python Django中实现用户文章编辑更新功能?

Django博客文章编辑功能故障求助

我用Django搭建了博客,想实现用户编辑自己文章的功能,看了不少教程视频还是无法正常运行。作为Django新手,我把相关代码贴出来,希望能得到帮助:

views.py

from django.shortcuts import render, redirect
from .models import Article
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from . import forms
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger


@login_required(login_url="/accounts/login/")
def article_list(request):
    articles = Article.objects.all().order_by('-date')
    paginator = Paginator(Article.objects.all().order_by('-date'), 6)
    page = request.GET.get('page')

    try:
        items = paginator.page(page)
    except PageNotAnInteger:
        items = paginator.page(1)
    except EmptyPage:
        items = paginator.page(paginator.num_pages)
    index = items.number - 1
    max_index = len(paginator.page_range)
    page_range = paginator.page_range[0:max_index]

    return render(request, 'articles/article_list.html', {'articles':articles, 'items':items, 'page_range':page_range})

@login_required(login_url="/accounts/login/")
def article_details(request, slug):
    article = Article.objects.get(slug=slug)
    return render(request, 'articles/article_details.html', {'article':article})

@login_required(login_url="/accounts/login/")
def article_create(request):
    if request.method == 'POST':
        form = forms.CreateArticle(request.POST, request.FILES)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.author = request.user
            instance.save()
            return redirect('articles:list')
    else:
        form = forms.CreateArticle()
    return render(request, 'articles/article_create.html', {'form':form})

@login_required(login_url="/accounts/login/")
def article_edit(request, slug):
    article = Article.objects.get(slug=slug)
    form = forms.CreateArticle(request.GET, request.FILES)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.author = request.user
        instance.save()
        return redirect('articles:list')
    return render(request, 'articles/article_edit.html', {'form':form})

我主要卡在article_edit视图的实现上。

urls.py

from django.conf.urls import url
from . import views

from .views import article_edit

app_name = 'articles'
urlpatterns = [
    url(r'^$',views.article_list, name="list"),
    url(r'^create/$', views.article_create, name="create"),
    url(r'^(?P<slug>[\w-]+)/$', views.article_details, name="details"),
    url(r'^(?P<slug>[\w-]+)/edit/$', views.article_edit, name="edit"),
]

我希望用url()来实现,和article_details的写法保持一致。

article_details.html(包含编辑按钮)

{% extends 'default.html' %}

{% block content %}
{% if article.author.id == user.id %}
    <nav class="UpdateArticle">
        <li><a href="{% url 'articles:edit' slug=article.slug %}" class="ArticleEdit">Edit</a></li>
        <li><a href="{% url 'articles:delete' %}" class="ArticleDelete">Delete</a></li>
    </nav>
{% endif %}
<div class="article-details">
    <div class="article">
        <img src="{{ article.thumb.url }}"/>
        <h2>{{ article.title }}</h2>
        <div class="infos">
            <p>Director: {{ article.director }}</p>
            <p>Protagonist(s): {{ article.protagonist }}</p>
        </div>
        <p>{{ article.body }}</p>
        <p class="author">Created by <br>{{ article.author }}</p>
        <p>{{ article.date }}</p>
    </div>
</div>
{% endblock %}

删除功能还没做,现在先专注搞定编辑功能。

article_edit.html

{% extends 'default.html' %}

{% block content %}
<div class="edit-article">
    <h2>Edit an article</h2>
    <form class="site-form" action="{% url 'articles:edit' slug=article.slug %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form }}
        <input type="submit" value="Update">
    </form>
</div>
<script src="/static/slugify.js"></script>
{% endblock %}

问题修正方案

1. 修复article_edit视图逻辑

当前视图存在3个核心问题:未区分请求方法、未关联现有文章实例、缺少权限校验。修改后的代码:

@login_required(login_url="/accounts/login/")
def article_edit(request, slug):
    article = Article.objects.get(slug=slug)
    
    # 仅允许文章作者编辑
    if article.author != request.user:
        return HttpResponse("你无权编辑这篇文章")
    
    if request.method == 'POST':
        # 传入POST数据、文件和现有文章实例实现更新
        form = forms.CreateArticle(request.POST, request.FILES, instance=article)
        if form.is_valid():
            form.save()
            # 编辑完成后跳回文章详情页更合理
            return redirect('articles:details', slug=article.slug)
    else:
        # GET请求时用现有文章数据填充表单
        form = forms.CreateArticle(instance=article)
    
    # 必须把article传给模板,因为模板中用到了{{ article.slug }}
    return render(request, 'articles/article_edit.html', {'form': form, 'article': article})

2. 调整URL匹配顺序

当前details的URL规则会优先匹配xxx/edit(因为[\w-]+会把xxx/edit整个当作slug),导致edit规则永远不会被触发。需要把edit规则移到details前面:

from django.conf.urls import url
from . import views

app_name = 'articles'
urlpatterns = [
    url(r'^$',views.article_list, name="list"),
    url(r'^create/$', views.article_create, name="create"),
    url(r'^(?P<slug>[\w-]+)/edit/$', views.article_edit, name="edit"),
    url(r'^(?P<slug>[\w-]+)/$', views.article_details, name="details"),
]

3. 确保表单类为ModelForm

如果你的forms.py中CreateArticle不是继承自ModelForm,需要修改为以下结构,这样才能通过instance参数实现数据初始化和更新:

from django import forms
from .models import Article

class CreateArticle(forms.ModelForm):
    class Meta:
        model = Article
        # 列出需要编辑的字段,根据你的Article模型调整
        fields = ['title', 'director', 'protagonist', 'body', 'thumb']

内容的提问来源于stack exchange,提问作者Mail Fun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:17:04