from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from .models import Article
from .forms import ArticleForm
# 创建文章
def article_create(request):
# 如果用户通过POST提交,通过request.POST获取提交数据
if request.method == "POST":
# 将用户提交数据与ArticleForm表单绑定
form = ArticleForm(request.POST)
# 表单验证,如果表单有效,将数据存入数据库
if form.is_valid():
form.save()
# 创建成功,跳转到文章列表
return redirect(reverse("blog:article_list"))
else:
# 否则空表单
form = ArticleForm()
return render(request, "blog/article_form.html", {
"form": form, })
# 更新文章
def article_update(request, pk):
# 从url里获取单篇文章的id值,然后查询数据库获得单个对象实例
article = get_object_or_404(Article, pk=id)
# 如果用户通过POST提交,通过request.POST获取提交数据
if request.method == 'POST':
# 将用户提交数据与ArticleForm表单绑定,进行验证
form = ArticleForm(instance=article, data=request.POST)
if form.is_valid():
form.save()
# 更新成功,跳转到文章详情
return redirect(reverse("blog:article_detail", args=[pk,]))
else:
# 否则用实例生成表单
form = ArticleForm(instance=article)
return render(request, "blog/article_form.html", {
"form": form, "object": article})
#blog/forms.py 中自定义的 ArticleForm类
from .models import Article
from django import forms
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'body']
render() 有4个参数。第一个是request, 第二个是模板的名称和位置,第三个是需要传递给模板的数据内容, 也被称为context object。第四个参数是可选参数content_type(内容类型)
get_object_or_404() 第一个参数是模型Models或数据集queryset的名字,第二个参数是筛选条件(比如pk = id, title = ‘python’)。当需要获取的对象不存在时,给方法会自动返回Http 404错误
# blog/urls.py
from django.urls import path, re_path
from . import views
urlpatterns = [
path('', views.MyClassView.as_view()),
]
Django提供了很多通用的基于类的视图,来简化视图的编写
类 | 作用 | 举例 |
---|---|---|
ListView | 展示对象列表 | 比如所有用户,所有文章 |
DetailView | 展示某个对象的详细信息 | 比如用户资料,文章详情 |
CreateView | 通过表单创建某个对象 | 比如创建用户,新建文章 |
UpdateView | 通过表单更新某个对象信息 | 比如修改密码,修改文字内容 |
FormView | 用户填写表单后转到某个完成页面 | |
DeleteView | 删除某个对象 |
# Create your views here.
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView, DetailView, CreateView, UpdateView, FormView, DeleteView
from .models import Article
from django.utils import timezone
from .forms import ArticleCreateForm
from myapp.forms import ContactForm
# ListView
class IndexView(ListView):
template_name = 'blog/article_list.html'
context_object_name = 'latest_articles'
def get_queryset(self):
return Article.objects.filter(author=self.request.user).order_by('-pub_date')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['now'] = timezone.now()
return context
# DetailView
class ArticleDetailView(DetailView):
queryset = Article.objects.all().order_by("-pub_date") # 一般不写
template_name = 'blog/article_detail.html'
context_object_name = 'article'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['now'] = timezone.now()
return context
# CreateView
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
template_name = 'blog/article_create_form.html'
form_class = ArticleCreateForm
def form_valid(self, form):
# form.do_something()
form.instance.author = self.request.user
return super(ArticleCreateView, self).form_valid(form)
# 对于CreateView, 重写它的 form_valid 方法不是必需,但很有用
# 当用户提交的数据是有效的时候,执行该方法
# 通过定义此方法做些别的事情,比如发送邮件,存取额外的数据
# form_valid方法一个常见用途就是(需要用户先登录再提交)
# UpdateView
class ArticleUpdateView(UpdateView):
model = Article
template_name = 'blog/article_update_form.html'
form_class = ArticleUpdateForm
def form_valid(self, form):
form.do_sth()
return super(ArticleUpdateView, self).form_valid(form)
def get_object(self, queryset=None):
obj = super().get_object(queryset=queryset)
if obj.author != self.request.user:
raise Http404()
return obj
# UpdateView的常用自定义方法是 get_object 方法。比如一个用户只能编辑自己发表的文章对象,当用户查看别人的对象时,返回http 404错误
# FormView
class ContactView(FormView):
template_name = 'contact.html'
form_class = ContactForm
success_url = '/thanks/'
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
# It should return an HttpResponse.
form.send_email()
return super().form_valid(form)
# 使用FormView, 当用户输入信息未通过表单验证,显示错误信息
# 当用户输入信息通过表单验证提交后,跳到其它页面
# 一般需要定义template_name, form_class和success_url
# DeleteView
class ArticleDelete(DeleteView):
model = Article
success_url = reverse_lazy('index')
# 删除后通过 reverse_lazy 方法返回到index页面
# Create your views here.
from django.views.generic import ListView
from .models import Article
class IndexView(ListView):
model = Article
# 上述类视图等同于下面函数视图:
def index(request):
queryset = Article.objects.all()
return render(request, 'blog/article_list.html', {
"article_list": queryset})
虽然只一行model = Article, 但ListView实际上在背后做了很多事情: