如何在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
相关产品推荐
相关产品推荐

