前言
这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题
于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。
微信小程序搜索:Python面试宝典
或可关注原创个人博客:https://lienze.tech
也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习
通用编辑视图
FormView
这是用来处理表单的视图;出错时,显示出关于表单验证的错误;如果成功,则跳转到新的url
class FormMixin(ContextMixin):
"""Provide a way to show and handle a form in a request."""
initial = {} # 初始化默认值
form_class = None # 某个表单类
success_url = None # 验证成功之后跳转的地址
prefix = None # 控制在表单页面中的name值前缀,用以区分不同表单的name属性
- FormView有一个非常重要的父类,用来控制分析表单
class ProcessFormView(View):
"""Render a form on GET and processes it on POST."""
def get(self, request, *args, **kwargs):
"""Handle GET requests: instantiate a blank version of the form."""
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
"""
Handle POST requests: instantiate a form instance with the passed
POST variables and then check if it's valid.
"""
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
class FormMixin(ContextMixin):
def get_form_class(self):
"""Return the form class to use."""
return self.form_class
def get_form(self, form_class=None):
"""Return an instance of the form to be used in this view."""
if form_class is None:
form_class = self.get_form_class()
return form_class(**self.get_form_kwargs())
在这个类中定义了主要的post请求,用来分析form表单是否是正确的输入,有关的self.form_valid和self.form_invalid函数定义如下,还是非常简单的,出错的话,会通过get_context_data将错误返回,成功的话将会通过get_success_url重定向
class FormMixin(ContextMixin):
def form_invalid(self, form):
"""If the form is invalid, render the invalid form."""
return self.render_to_response(self.get_context_data(form=form))
def form_valid(self, form):
"""If the form is valid, redirect to the supplied URL."""
return HttpResponseRedirect(self.get_success_url())
- 来做一个简单的测试,使用FormView进行表单页面的提供以及数据的验证入库
#forms
class UserForm(forms.Form):
name = forms.CharField(max_length=30)
#views
class FormViewTest(FormView):
model = User # 添加model全局属性,以供代码整洁良好复用
template_name = 'test_form.html' # 因为FormView并没有自动提供模版后缀,需要我们手动指定
form_class = UserForm # 表单页面渲染的表单类
success_url = '/' # 表单验证成功之后的重定向地址
prefix = 'a1' # 在表单页面的name属性值前缀,一般不要重复即可
def post(self, request, *args, **kwargs): # 重写post方法,因为我们要数据入库
form = self.get_form()
if form.is_valid():
name = form.cleaned_data['name']
self.model._default_manager.create(name=name) # 验证之后的数据入库
return self.form_valid(form)
else:
return self.form_invalid(form)
- 需要配合的表单页面就更加简单了
<!-- test_form.html -->
<form action="" method="POST">
{% csrf_token %}
{{ form }}
<button type="submit">提交</button>
</form>
- 注意:如果在继承类中使用
success_url
属性,进行反向解析路由命名,要使用reverse_lazy而非reverse,因为success_url
属性为类属性,而Django的urlconf加载在所有类加载之后,而reverse_lazy可以让success_url
的加载在路由被访问时。
CreateView
快速创建某个模型数据
因为继承父类太多了,简单一些,直接列举了他一些设置属性
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
"""
View for creating a new object, with a response rendered by a template.
"""
template_name_suffix = '_form'
# 这个视图默认的表单页地址是:appname/modelname_from.html
#---ModelFormMixin---
fields = [] # 模型类中需要表单提供的字段值
#---FormMixin---
initial = {} # 初始化默认值
form_class = None # 某个表单类
success_url = None # 验证成功之后跳转的地址
prefix = None # 控制在表单页面中的name值前缀,用以区分不同表单的name属性
#---SingleObjectMixin---
model = None # 需要表单创建的模型类
- 在ModelFormMixin这个类中重写了form_valid函数,不光进行了数据校验,还进行了数据入库
class ModelFormMixin(FormMixin, SingleObjectMixin):
def form_valid(self, form):
"""If the form is valid, save the associated model."""
self.object = form.save()
return super().form_valid(form)
在ModelFormMixin类中还使用了modelform_factory函数,这是为什么我们不需要在这个视图类中进行表单类的定义
可以单独使用 modelform_factory() 函数来直接从 Model 创建表单。在不需要很多自定义的情况下是更方便的,比如
UserForm = modelform_factory(User, fields=("name",))
- 列举一个使用示例
class CreateTest(CreateView):
model = Info
fields = ['user','info']
success_url = '/' # 数据创建成功之后的跳转地址
<form action="" method="post">
{% csrf_token %}
{{ form }}
<button type="submit">提交</button>
</form>
字段中的多对一,多对多关系会自动成为下拉菜单或复选框的样式供你使用,非常的简单!
UpdateView
更新某个数据的视图类,更新通过链接传递的pk值,或者对应的字段过滤条件,参见DetailView
class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView):
"""View for updating an object, with a response rendered by a template."""
template_name_suffix = '_form'
# 默认的表单页面后缀,appname/modelname_form.html
#---FormMixin---
initial = {} # 初始化默认值
form_class = None # 某个表单类
success_url = None # 验证成功之后跳转的地址
prefix = None # 控制在表单页面中的name值前缀,用以区分不同表单的name属性
#---SingleObjectMixin---
model = None # 数据模型,将在视图页面展示数据
queryset = None # queryset如果提供,则值queryset取代设置model的值
slug_field = 'slug' # 过滤的字段
context_object_name = None
slug_url_kwarg = 'slug' # 过滤条件,通过链接参数给定;如 a.com/<str:slug>/
pk_url_kwarg = 'pk' # 启用主键作为链接参数过滤条件
query_pk_and_slug = False # 当依赖主键查询不为空时,设置该值为True,可以继续过滤字段,就是又过滤pk还过滤field
使用UpdateView,首先要通过路由传递对应的pk或者指明的slug_url_kwarg字段确定要更新的数据是哪个,然后进行更新,更新完毕会跳转到由success_url定义的路由之中。
- 看个demo,比如我想更新张三
class UpdateTest(UpdateView):
model = Info
fields = ['id','info','user']
success_url = '/'
slug_field = 'user__name'
# 外键关联关系可以通过链式查询给定
slug_url_kwarg = 'user_name'
# 在链接中的给定传递给user__name的形参名
path('update/<str:user_name>/',UpdateTest.as_view())
# 对应上方的user_name
DeleteView
删除
self.get_object()
获取到的数据对象
class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView):
"""
View for deleting an object retrieved with self.get_object(), with a
response rendered by a template.
"""
template_name_suffix = '_confirm_delete'
# 默认模版的路径是appname/modelname_confirm_delete.html
#---SingleObjectMixin---
model = None # 数据模型,将在视图页面展示数据
queryset = None # queryset如果提供,则值queryset取代设置model的值
slug_field = 'slug' # 过滤的字段
context_object_name = None
slug_url_kwarg = 'slug' # 过滤条件,通过链接参数给定;如 a.com/<str:slug>/
pk_url_kwarg = 'pk' # 启用主键作为链接参数过滤条件
query_pk_and_slug = False # 当依赖主键查询不为空时,设置该值为True,可以继续过滤字段,就是又过滤pk还过滤field
-
在
get
方式访问时,会先返回符合匹配条件的数据对象,默认的模版上下文名为object
-
在
post、delete
方式访问时,会将所匹配的数据对象删除
class DeleteTest(DeleteView):
model = Info
slug_url_kwarg = 'user_name'
slug_field = 'user__name' # user为外键,根据外键的链式查询进行筛选
success_url = '/'
context_object_name = 'info' # 当get访问时,模版页面渲染时的上下文变量名
path('delete/<str:user_name>/',DeleteTest.as_view()),