版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/bbwangj/article/details/98720627
Class-based views是Django为解决建站过程中的常见的呈现模式而建立的。具有如下几个原则:
django自带的view如下表所示:
类名 | 功能 | 例子 |
---|---|---|
View | 基本View, 可以在任何时候使用 | 见后面详细介绍 |
RedirectView | 重新定向到其他URL | 将访问"/log-in/"的用户重新定向到"/login/" |
TemplateView | 显示Django HTML template | 一般网站中使用模板显示的页 |
ListView | 显示对象列表 | 文章列表页 |
DetailView | 显示对象详情 | 文章详细页 |
FormView | 提交From | 网站联系我们或emai订阅form |
CreateView | 创建对象 | 创建新文章页 |
UpdateView | 更新对象 | 修改文章页 |
DeleteView | 删除对象 | 删除文章页 |
Generic date views | 显示一段时间内的对象 | 按时间归类的博客 |
表示对象列表的一个页面.
执行这个视图的时候,self.object_list
将包含视图正在操作的对象列表(通常是一个查询集,但不是必须).
属性:
model
提供的值方法:
queryset
属性.可以通过重写该方法实现动态过滤.让这种方式能够工作的关键点,在于当类视图被调用时,各种有用的对象被存储在self
上,同request(self.request)
一样,其中包含了从URLconf中获取到的位置参数(self.args
)和关键字参数(self.kwargs
).
执行这个视图的时候,self.object
将包含视图正在操作的对象.
属性:
queryset
的值优先于model
的值.方法:
queryset
.如果设置了queryset
属性,get_queryset()
默认返回它的值.queryset
,该queryset
将作为对象的查询源,否则,将使用get_queryset()
.get_object()
从视图的所有参数中查找pk_url_kwarg
参数,如果找到了这个参数,该方法使用这个参数的值执行一个基于逐渐的查询.如果这个参数没有找到,该方法查找slug_url_kwarg
参数,使用slug_field
字段执行针对slug的查询.当query_pk_and_slug
为True
时,get_object()
将使用主键和slug执行查询.object
属性被视图赋值(即使是None).它返回一个包含这些内容的字典:
object
:这个视图显示的对象(self.object
)
context_object_name
:self.object
也将存储在get_context_object_name()
返回的名称中,该名称默认为模型的小写名称.
3.FormView
显示表单的视图,验证错误时,重新显示表单并显示错误信息;成功时,重定向到一个新的URL. 属性:
success_url
.get_success_url()
,可以覆盖该方法在以上行为之间添加额外的动作.该方法必须返回一个HttpResponse
.显示用于创建对象的表单的视图,通过验证错误信息重新显示视图,并且保存对象. 属性:
ModelForm
的Meta.fields
相同.如果你是自动生成表单类,那么该属性不能省略.显示用于编辑现有对象的表单的视图,重新显示具有验证错误信息的视图,并且保存对象.这里使用从对象模型自动生成的表单(除非手动制定表单类).
该视图用法与CreateView基本相同,仅在BaseUpdateView中对get()
和post()
的内部实现有区别.
显示确认页面并删除现有对象的视图.仅当请求方法为POST时,才会删除给定的内容.如果此视图是通过GET提取的,它将显示一个确认页面,其中包含POST到同一网址的表单. 属性:
delete()
方法,然后重定向到success_url
.1、创建django工程,创建名为crud的app,此处略过
2、 修改models.py
class employee(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=30)
address = models.CharField(max_length=60)
city = models.CharField(max_length=60)
email = models.EmailField(max_length=30)
phone = models.CharField()
wechat = models.CharField(max_length=30)
QQ = models.CharField()
def __unicode__(self):
return self.name
class Meta:
ordering = ["-id"]
3、配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crud',
]
4、数据迁移
python manage.py makemigrations crud
python manage.py migrate crud
5、修改urls,views
crud中的urls
from django.conf.urls import url
from crud import views
urlpatterns = [
url(r'^$', views.EmployeeList.as_view(), name='employee_list'),
url(r'^add', views.EmployeeCreate.as_view(), name='employee_add'),
url(r'^update/(?P<pk>\d+)$', views.EmployeeUpdate.as_view(), name='employee_update'),
url(r'^delete/(?P<pk>\d+)$', views.EmployeeDelete.as_view(), name='employee_delete'),
url(r'employee_detail/(?P<pk>\d+)/$', views.EmployeeDetail.as_view(), name='employee_detail'),
]
工程中urls
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^crud/', include('crud.urls')),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render, redirect
# Create your views here.
from django.http import HttpResponse, HttpResponseRedirect
from django.views.generic import TemplateView,ListView
from django.utils import timezone
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.core.urlresolvers import reverse_lazy
from crud.models import employee
class EmployeeList(ListView):
model = employee
class EmployeeCreate(CreateView):
model = employee
success_url = reverse_lazy('employee_list')
fields = ['id', 'name', 'address', 'city', 'email', 'phone', 'wechat', 'QQ']
def add(request):
form = employee(request.POST or None)
if form.is_valid():
instance.save()
context = {
'form': form,
}
#如果没有有效提交,则仍留在原来页面
return render(request, 'employee_list.html', context)
class EmployeeUpdate(UpdateView):
model = employee
success_url = reverse_lazy('employee_list')
fields = ['id', 'name', 'address','city', 'email', 'phone','wechat','QQ']
class EmployeeDelete(DeleteView):
model = employee
success_url = reverse_lazy('employee_list')
class EmployeeDetail(DetailView):
model = employee #将 model 指定为Publisher,告诉 Django 我要获取的模型是 Publisher。
context_object_name = 'employee_detail' #指定获取的模型列表数据保存的变量名。这个变量会被传递给模板。
def get_context_data(self, **kwargs):
context = super(EmployeeDetail, self).get_context_data(**kwargs)
context['now'] = timezone.now()
return context
6、新建模板 employee_list.html
<ul>
{% for emp in object_list %}
<li>{{ emp.id }}     {{ emp.name }}    {{ emp.address }}   {{ emp.city }}    
{{ emp.email }}    {{ emp.phone }}   {{ emp.wechat }}    {{ emp.QQ }}:
<a href="{% url "employee_update" emp.id %}">修改</a>
<a href="{% url "employee_delete" emp.id %}">删除</a>
</li> 
{% endfor %}
</ul>
<a href="{% url "employee_add" %}">新增</a>
employee_form.html
<title>Title</title>
<form method="post">
<table>
{% csrf_token %}
{{ form }}
</table>
<input type="submit" value="Submit" />
</form>
employee_confirm_delete.html
<form method="post">{% csrf_token %}
确实要删除 "{{ object }}" ?
<input type="submit" value="Submit" />
</form>
employee_detail.html
<h1>你好,{{ object.name }}</h1>
<h2>工号:{{ object.id }}</h2>
<p>姓名:{{ object.name }}</p>
<p>邮箱地址:{{ object.email }}</p>
<p>所在城市: {{ object.city }}</p>
<p>电话号码: {{ object.phone }}</p>
<p>详细地址: {{ object.address }}</p>
<p>微信: {{ object.wechat }}</p>
<p>QQ: {{ object.QQ }}</p>
7、启动服务python manage.py runserver
浏览器中输入 http://127.0.0.1:8000/crud/ 即可对员工进行增加、删除、修改
-----UpdateView和CreateView-----
我们有了Project和Schedule列表显示后,现在需要添加新增和修改的操作。可以直接用Django通用视图里的UpdateView和CreateView。根据官网文档的例子,我们先在projtrack/views.py中添加项目新增和修改视图的代码:
# projtrack/views.py
...
# 修改项目视图
class ProjUpdView(generic.UpdateView):
model = Project
fields = ['project_name', 'description', 'project_status']
template_name = 'projtrack/update_form.html'
# 新增项目视图
class ProjNewView(generic.CreateView):
model = Project
fields = ['project_name', 'description', 'project_type', 'project_status']
template_name = 'projtrack/update_form.html'
...
因为编辑和新增页面的前端代码基本一样,我们在这里都指定了template为update_form。也可指定不同的模板。另外也可用template_name_suffix参数去指定模板。比如,如果设定template_name_suffix = '_create_form', 则用到的模板将会是projtrack/project_create_form.html。
这里projtrack/update_form.html代码如下:
{% extends "projtrack/index.html" %}
{% block body %}
{% if user.is_authenticated %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input class="btn btn-default" type="submit" value="Update" />
</form>
{% endif %}
{% endblock %}
注意:
在所有的 POST 表单元素时,需要加上一个 {% csrf_token %} tag。这是Django提供的CSRF防护机制。 {{ form.as_p }} 表示渲染表单为一系列的p标签,每个p标签包含一个字段:
<p>
<label for="id_subject">Subject:</label>
<input id="id_subject" type="text" name="subject" maxlength="100" />
</p>
其它form在模版中的渲染方式还包括:
form.as_ul:渲染表单为一系列的li标签,每个li 标签包含一个字段 form.as_table:输出表单为一个HTML的table。 for field in form:通过迭代form,获取其中的所有field。field可引用的包括:{{ field.label_tag }} , {{ field }} , {{ field.errors }} 。{{ field.label_tag }}输出为field的label元素,{{ field }}输出为field的input,{{ field.errors }}为field的errors元素(errors一般在form验证出错的时候显示)。 form.fieldname:直接将form作为一个dict,引用其每一个field,比如{{ form.title }} 引用form中的title这个field。这种方式一般用于form需要更加精准的样式的时候,逐个元素逐个元素的编排到html中。
完成后可在页面上新增或修改项目信息。不过点击Update后会有一个报错:191989-055d8b7a362f2603.png
意思是新增后修改完成后我们没有定义一个redirect的url去跳转。根据报错的提示,我们可以直接在视图下给success_url参数赋值,或在模型中去定义get_absolute_url()方法,去设置成功后跳转的url。这里我们在模型中添加:
# projtrack/model.py
class Project(models.Model):
...
def get_absolute_url(self):
return reverse('projtrack:project')
这样,在新增或修改项目成功就就跳转到项目列表页面
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有