300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 验证码 文件上传和中间件

验证码 文件上传和中间件

时间:2022-11-19 03:15:47

相关推荐

验证码 文件上传和中间件

1、验证码

1、作用

为了更好的保障请求的合法性,防止无效访问,恶意访问,暴力破解等攻击。

pip install pillow

2、验证码的使用

导入第三方库

文件直接复制粘贴到自己项目的app中就可以

生成验证码

from django.shortcuts import render,HttpResponseimport random,stringfrom .captcha.image import ImageCaptcha#导入当前目录的验证码包# Create your views here.def captch(request):image=ImageCaptcha()#生成验证码对象code=random.sample(string.ascii_letters+string.digits,5)#随机产生五位数的验证码code=''.join(code)#把列表拼接成字符串print(code)request.session['code']=code#存入页面的session中,为了以后的验证,注意session的作用。data = image.generate(code)#生成验证码图片return HttpResponse(data,'image/png')#返回给要验证码的界面

在HTML使用验证码

<input type="text" name="code"><img src="{% url 'ems:captch' %}" id="image_code" width="80px" height="30px" align="center"> <a href="javascript:void(0)" onclick="change()">换一张</a><script>function change() {var url = "{% url 'capt:captch' %}?"+new Date().getTime()#根据时间戳更换验证码$('#image_code').attr('src',url) //刷新验证码}</script>

验证验证码

def registlogic(request):code = request.session.get('code')if code.lower() == request.POST.get('code').lower():return HttpResponse("成功")else:return HttpResponse("失败")

2、文件上传

1、简介

Django的模型类(django.db.models.Model)提供了两个FileField和ImageField用于上传文件和图片。而ImageField继承自FileField。使用Django的ImageField需要提前安装pillow模块。

2、使用用例,为用户上传头像

1、设置图片的保存路径

#settings.pyMEDIA_ROOT = os.path.join(BASE_DIR,"media") # 项目目录下的media目录 需要在项目目录下创建media目录

2、定义Model

class User(models.Model):name = models.CharField(max_length=20)#文件将存于 MEDIA_ROOT目录下的pics目录下pic = models.ImageField(upload_to="pics")

生成移植文件并执行

3、定义form表单

<form action="{% url 'ems:uplogic_logic' %}" method="post" enctype="multipart/form-data">#上传文件{% csrf_token %}用户名:<input type="text" name="name"><br>头像:<input type="file" name="source"><input type="submit" value="提交"></form>

4、定义view函数

import uuid,osdef uplogic_logic(request):try:name = request.POST.get('name')file = request.FILES.get('source')file.name =str(uuid.uuid4())+os.path.splitext(file.name)[1] # 生成唯一文件名,防止上传文件相同的用户名user = User.objects.create(name=name, pic=file)return HttpResponse("上传成功")except:return HttpResponse("上传失败")

注意,此时数据库中存储的路径是相对于MEDIA_ROOT的路径所以可以将MEDIA_ROOT设置为静态资源根目录,可便于后续的头像回显

5、回显图片

1、设置今天资源根目录

MEDIA_ROOT = os.path.join(BASE_DIR,'media')STATIC_URL = '/static/'STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), MEDIA_ROOT ]

2、view函数

def query(request):users = User.objects.all()return render(request,'uploadfile_demo/detail.html',{'users':users})

3、模板中使用

{% load static %}<img src="{% static user.headpic.url %}" width="50px">users是view传入参数,headpic是列名,url是表示当前图片的路径

三、分页显示

Django自身提供了一些类来实现管理分页,数据被分在不同的页面中,并带有上一页下一页的标签,这个类叫做Paginator

2、Paginator分页器

pagtor = Paginator(User.objects.all(),per_page=3)User.objects.all()要分页的对象per_age每页显示的个数

属性

Paginator.count:每一页面的条数 Pagnator.num_pages:页面总数。pagiator.page_range:页面范围,从1开始,例如[1,2,3,4]。

page对象

Paginator.page(number):根据参数number返回一个Page对象,表示第number页。

page = Paginator(User.objects.all(),per_page=3).page(1) # 获取第一页也就是获取第一页所有对象的集合

page方法

Page.has_next() 如果有下一页,则返回True。Page.has_previous() 如果有上一页,返回 True。Page.has_other_pages() 如果有上一页或下一页,返回True。Page.next_page_number() 返回下一页的页码。如果下一页不存在,抛出InvlidPage异常。Page.previous_page_number() 返回上一页的页码。如果上一页不存在,抛出InvalidPage异常。Page.start_index() 返回当前页上的第一个对象,相对于分页列表的所有对象的序号,从1开始。比如,将五个对象的列表分为每页两个对象,第二页的start_index()会返回3。Page.end_index() 返回当前页上的最后一个对象,相对于分页列表的所有对象的序号,从1开始。 比如,将五个对象的列表分为每页两个对象,第二页的end_index() 会返回 4。

属性

Page.object_list当前页上所有对象的列表。Page.number当前页的序号,从1开始。Page.paginator相关的Paginator对象。

三、分页

# http://localhost:8000/page/index/?num=2def index(request):number = request.GET.get('num',1)pagtor = Paginator(User.objects.all(),per_page=4)page = pagtor.page(number) # 某一页的page对象return render(request,'page_demo/index.html',{'page':page})

显示上一页下一页{% if page.has_previous %}<a href="{% url 'ems:show' %}?number={{ page.previous_page_number }}">上一页</a>{% endif %}{% for number in page.paginator.page_range %}<a href="{% url 'ems:show' %}?number={{ number }}">{{ number }}</a>{% endfor %}{% if page.has_next %}<a href="{% url 'ems:show' %}?number={{ page.next_page_number }}">下一页</a>{% endif %}

四、中间件

作用

常用作view中冗余功能的抽取,如每个页面(或某些页面)在访问前强制登录。减少代码冗余,提高代码的复用性。但是注意,中间件会把所有的都拦截

定义中间件

class MyMiddleware(MiddlewareMixin):# 自定义的中间件def __init__(self,get_response):#初始化super().__init__(get_response)print("init1")#view处理请求前执行def process_request(self,request): #某一个viewprint("request:",request)#在process_request之后View之前执行def process_view(self,request, view_func, view_args, view_kwargs):print("view:",request,view_func,view_args,view_kwargs)#view执行之后,响应之前执行def process_response(self,request,response):print("response:",request,response)return response #必须返回response#如果View中抛出了异常def process_exception(self,request,ex):#View中出现异常时执行print("exception:",request,ex)

激活中间件

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware',....'emsapp.MyMiddleWate.MyMiddleware',# 注册自定义中间件,尽量放在最后注册app名,文件名,函数名]

强制登录实例

from django.shortcuts import redirectfrom django.utils.deprecation import MiddlewareMixinclass MyMiddleware(MiddlewareMixin): # 自定义的中间件def __init__(self, get_response): # 初始化super().__init__(get_response)print("init1")# view处理请求前执行def process_request(self, request): # 某一个viewprint("request:", request)# 在process_request之后View之前执行def process_view(self, request, view_func, view_args, view_kwargs):# print("view:", request, view_func, view_args, view_kwargs)if 'login' in request.path or 'regist' in request.path or 'captch' in request.path:passelse:res = request.session.get('login')if res:return redirect(request,'ems:show')else:return redirect(request,'ems:login')# view执行之后,响应之前执行def process_response(self, request, response):print("response:", request, response)return response # 必须返回response# 如果View中抛出了异常def process_exception(self, request, ex): # View中出现异常时执行print("exception:", request, ex)

五、CSRF

作用

CSRF(Cross-site request forgery)跨站请求伪造,是一种常见的网络攻击手段。

使用

在表单的POST后加{% csrf_token %}<form action="" method="post">{% csrf_token %}....</form>

原理

1. 在发送请求时,通过CsrfViewMiddleware 在服务器端生成一个随机的token(令牌),在render渲染模板时存放于form单的隐藏域和cookie中2. 当再次form发送请求时,会携带隐藏域令牌和cookie中的令牌,此时CsrfViewMiddleware 会先于View执行,去判断两块令牌是否一致,验明正身。

六、Admin管理后台

1、简介

Admin站点是Django有别于其它Web框架最重要的一点

admin通过读取你的模型数据,快速构造出一个可以对实际数据进行管理的Web站点

常用于开发测试,简单管理等场合,适用于部门内部为工作方便的场合,但不建议在生产环境中使用。

2、admin使用步骤

2.1 安装django.contrib.admin

确保,在settins.py中的INSTALLED_APPS 中安装了admin,它会扫描每个app的admin.py,进而支持后台管理。

INSTALLED_APPS = ['django.contrib.admin', # 安装admin'django.contrib.auth', # 下面四个为admin的依赖模块'django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages',...]

2.2 注册Model

在App的admin.py中注册需要管理的Model类

admin.site.register(User)

2.3 创建管理员账户

python manage.py createsuperuser

2.4 启动服务

python manage.py runserver

2.5 访问后台管理页面

http://localhost:8000/admin

在URLconf中默认已经配置好admin的访问路径

urlpatterns = [path('admin/', admin.site.urls),...]

3、定制admin

3.1 User(Models)管理页面

[外链图片转存失败(img-cpXUZJ3z-1568627975119)(.\Django-notes-pic\admin界面.png)]

修改后台列表显示User Object,改为更为直观的信息:

class User(models.Model):name = models.CharField(max_length=30)imagepath = models.ImageField(upload_to='Mr_lee')def __str__(self):# 重写__str__方法return self.name

[外链图片转存失败(img-A4CAhaB3-1568627975120)(.\Django-notes-pic\修改admin后台User显示.png)]

3.2 操作选项位置
定制前:

[外链图片转存失败(img-Vyc2786Y-1568627975121)(.\Django-notes-pic\操作选项位置.png)]

**补充:**注册admin的另一种方式装饰器

@admin.register(User)# 等价于 admin.site.register(User)class UserAdmin(admin.ModelAdmin):#定制操作选项位置actions_on_top = Trueactions_on_bottom = True

定制后:

[外链图片转存失败(img-J2MLROWJ-1568627975121)(C:\Users\ADMINI~1\AppData\Local\Temp\1531814252335.png)]

3.3 定制列名
定制前:

[外链图片转存失败(img-wfarZbs9-1568627975122)(C:\Users\ADMINI~1\AppData\Local\Temp\1531814668417.png)]

定制后:

[外链图片转存失败(img-KXBmHm7A-1568627975123)(C:\Users\ADMINI~1\AppData\Local\Temp\1531814709514.png)]

代码:

class UserAdmin(admin.ModelAdmin):list_display = ['name','imagepath'] # 定制显示的列名

定制列名的别名(可以是中文)

class User(models.Model):name = models.CharField(max_length=30)imagepath = models.ImageField(upload_to='Mr_lee')def other_name(self):return self.nameother_name.short_description = '姓名' # 改列名other_name.admin_order_field = 'name' # 保证改列名后依然可以排序def other_path(self):return self.imagepathother_path.short_description = '图片路径'other_name.admin_order_field = 'imagepath'

# -- admin.py -- #class UserAdmin(admin.ModelAdmin):list_display = ['other_name','other_path'] # 定制显示的列名的别名 注意使用的是other_name

[外链图片转存失败(img-Wsi0kANL-1568627975124)(.\Django-notes-pic\列名别名.png)]

3.4 定制Model名
定制前:

[外链图片转存失败(img-MLRe7DlU-1568627975125)(.\Django-notes-pic\定制Model名)]

定制后:

[外链图片转存失败(img-KnbYuncK-1568627975126)(.\Django-notes-pic\model名)]

代码:

class User(models.Model):...class Meta:verbose_name = "用户"# 修改Model名verbose_name_plural = "用户" # 复数Model名 默认为users

3.5 定制过滤查询栏
定制前:

[外链图片转存失败(img-NjemSxPd-1568627975126)(.\Django-notes-pic\定制查询栏前)]

定制后:

[外链图片转存失败(img-9u9cdOhN-1568627975127)(.\Django-notes-pic\查询栏)]

代码:

class UserAdmin(admin.ModelAdmin):list_display = ['other_name','other_path'] list_filter = ['name','imagepath'] # 定制过滤查询栏

3.6 定制分页
定制前:

[外链图片转存失败(img-fEgSy1tf-1568627975128)(.\Django-notes-pic\定制分页前)]

定制后:

[外链图片转存失败(img-7KPskagj-1568627975129)(E:\Python Web\Python-Web-Lee\05 Django\Django-notes-pic\分页)]

3.7 定制搜索框
定制前:

[外链图片转存失败(img-7KitTvRQ-1568627975130)(.\Django-notes-pic\定制搜索框前)]

定制后:

[外链图片转存失败(img-VGxI8MyI-1568627975130)(.\Django-notes-pic\搜索框)]

代码:

class UserAdmin(admin.ModelAdmin):search_fields = ['name'] #可以以哪列作为条件搜索,会增加搜索框

3.8 定制可操作的列
定制前:

[外链图片转存失败(img-e52CUJ7v-1568627975131)(.\Django-notes-pic\定制可操作的列前)]

定制后:

[外链图片转存失败(img-9AGIm8bW-1568627975132)(.\Django-notes-pic\可操作的列)]

代码:

class UserAdmin(admin.ModelAdmin):fields = [('name', 'imagepath')] #增加和修改页显示的列,且name和imagepath列在一行显示

3.9 定制分组显示
定制前:

[外链图片转存失败(img-8BZtMiJt-1568627975132)(.\Django-notes-pic\定制分组前)]

定制后:

[外链图片转存失败(img-1d4WJqG0-1568627975133)(.\Django-notes-pic\分组显示)]

代码:

class UserAdmin(admin.ModelAdmin):...fieldsets = (('基本信息',{'fields':['name']}),('头像',{'fields':['imagepath']}))

3.10 关联显示

class Order(models.Model):title = models.CharField(max_length=30)price = models.FloatField()user = models.ForeignKey(to=User,on_delete=models.CASCADE)

class OrderInline(StackedInline):model = Order@admin.register(User)class UserAdmin(admin.ModelAdmin):inlines = [OrderInline]

七、Form(了解)

可以快速定制前端的form表单,并提供参数接收,数据验证。功能看似很全面

但实则使用价值不大,因为有众多前端框架,可以更专业的定制前端逻辑,而django如此定制有些越俎代庖,而且会影响前端框架的建设,无法和前端人员或前端技术对接(如:easyUI,bootstrap等)

所以,此章节请自学,了解即可!

class UserForm(forms.ModelForm):class Meta:model = User2#fields=["name","age","gender"]exclude=["salary2"]

def aa(request):print("goto a template")render(request,"xx.html",{"form":UserForm()})

xx.html<form action = "xxx" method="post">{% csrf_token %}<table>{{form }}<tr><td colspan="2" align="center"><input type="submit" value="Submit" /></td></tr></table></form>

def test3(request):form = UserForm(request.POST)if form.is_valid():print("表单数据合法")#{'name': 'zzz', 'age': 18, 'gender': True, 'birth': datetime.date(, 11, 12),...}data = form.cleaned_dataprint(data)return render(...)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。