python - 如何在Python Django 中更新文章?

标签 python django edit blogs

我使用 Django 制作了一个博客。我看了很多视频来制作一个用户可以更新/编辑自己的文章的功能。但我没有让它发挥作用。我是 Django 的新手,所以如果有人能帮助我,我将不胜感激。

这是我的观点.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
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中执行 View 。

这是 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 %}

最佳答案

将实例传递给表单:

from django.shortcuts import get_object_or_404


@login_required(login_url="/accounts/login/")
def article_edit(request, slug):
    article = get_object_or_404(Article, slug=slug)
    if request.method == 'POST':
        form = forms.CreateArticle(request.GET, request.FILES, <b>instance=article</b>)
        if form.is_valid():
            instance.author = request.user
            form.save()
            return redirect('articles:list')
    else:
        form = forms.CreateArticle(<b>instance=article</b>)
    return render(request, 'articles/article_edit.html', {'form': form})

您可能还想限制对作者的访问,因此:

from django.shortcuts import get_object_or_404


@login_required(login_url='/accounts/login/')
def article_edit(request, slug):
    article = get_object_or_404(Article, slug=slug<b>, author=request.user</b>)
    if request.method == 'POST':
        form = forms.CreateArticle(request.GET, request.FILES, instance=article)
        if form.is_valid():
            form.save()
            return redirect('articles:list')
    else:
        form = forms.CreateArticle(instance=article)
    return render(request, 'articles/article_edit.html', {'form': form})

但是,此类 View 可以简化为使用简单的 UpdateView [Django-doc] :

from django.contrib.auth.mixins import LoginRequiredMixin
from django.url import reverse_lazy
from django.views.generic import UpdateView


class ArticleEditView(LoginRequiredMixin, <b>UpdateView</b>):
    login_url = '/accounts/login/'
    model = Article
    success_url = reverse_lazy('articles:list')
    form_class = forms.CreateArticle

如果我们想限制只有作者才能访问:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import UpdateView


class ArticleEditView(LoginRequiredMixin, UpdateView):
    login_url = '/accounts/login/'
    model = Article
    form_class = forms.CreateArticle
    success_url = reverse_lazy('articles:list')

    def get_queryset(self, *args, **kwargs):
        return (
            super().get_queryset(*args, **kwargs).filter(<b>author=self.request.user</b>)
        )

或者您可以将其重定向到已编辑文章的详细信息页面:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import UpdateView


class ArticleEditView(LoginRequiredMixin, UpdateView):
    login_url = '/accounts/login/'
    model = Article
    form_class = forms.CreateArticle

    def get_queryset(self, *args, **kwargs):
        return (
            super().get_queryset(*args, **kwargs).filter(author=self.request.user)
        )

    def get_success_url(self):
        return reverse('articles:details', kwargs={'slug': <b>self.object.slug</b>})

Note: Usually a Form or a ModelForm ends with a …Form suffix, to avoid collisions with the name of the model, and to make it clear that we are working with a form. Therefore it might be better to use ArticleForm instead of CreateArticle.


Note: It is often better to use get_object_or_404(…) [Django-doc], then to use .get(…) [Django-doc] directly. In case the object does not exists, for example because the user altered the URL themselves, the get_object_or_404(…) will result in returning a HTTP 404 Not Found response, whereas using .get(…) will result in a HTTP 500 Server Error.

关于python - 如何在Python Django 中更新文章?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75827362/

相关文章:

python - 在 Python App Engine 中,如何唯一标识在开发 SDK 上运行的应用程序实例?

python - Heroku - Django : Had to change every mentioning of `myproject` into `app` to get my site working. 将来如何最好地避免这种情况?

php - 了解Mysql 'on duplicate key'

python - pip,如何删除死索引基 url

python - 如何使 django 全局可用

jquery - 创建与 CSS/HTML 相关的丰富动态单页 Django Web 应用程序的最佳方法

django - 如何检查模型是否为空

windows - 使用 windows azure 实现视频编辑套件

json - 如何在基于字段值替换项目的同时在 jq 中输出整个文档?

python - 使用 Python 仅向 CSV 文件添加一次 header - 正在创建实时数据