Django:Admin,Cookie,Session
一. Admin的配置
1.Admin基础设置
admin是django强大功能之一,它能够从数据库中读取数据,呈现在页面中,进行管理。默认情况下,它的功能已经非常强大,如果你不需要复杂的功能,它已经够用,但是有时候,一些特殊的功能还需要定制,比如搜索功能,下面这一系列文章就逐步深入介绍如何定制适合自己的admin应用。
<1> 在settings中设置Admin界面显示语言
LANGUAGE_CODE = 'en-us' #LANGUAGE_CODE = 'zh-hans'
<2> 认识ModelAdmin,管理界面的定制类,如需扩展特定的model界面需从该类继承。
<3>注册model类到admin的两种方式:
1) 使用register的方法
admin.site.register(Book,MyAdmin)
2) 使用register的装饰器
@admin.register(Book)
<4>掌握一些常用的设置技巧
list_display:指定要显示的字段
search_fields:指定搜索的字段
list_filter:指定列表过滤器
ordering:指定排序字段
list_per_page:设置每页显示多少条记录,默认是100条
list_editable:设置默认可编辑字段
fk_fields: 设置显示外键字段
date_hierarchy:按Admin自制表中的时间字段过滤
from django.contrib import admin from ORM_Study.models import *# Register your models here. # @admin.register(book)#----->单给某个表加一个定制 class MyAdmin(admin.ModelAdmin):list_display = ("title", "price","publish")search_fields = ("title","publish__name")list_filter = ("publish",)ordering = ("price",)list_per_page = 3date_hierarchy ="date" admin.site.register(book,MyAdmin)
View Code
<5>Admin常用设置详解
在admin.py中只需要讲Mode中的某个类注册,即可在Admin中实现增删改查的功能,如:
admin.site.register(models.UserInfo)
但是,这种方式比较简单,如果想要进行更多的定制操作,需要利用ModelAdmin进行操作,如:
方式一:class UserAdmin(admin.ModelAdmin):list_display = ('user', 'pwd',)admin.site.register(models.UserInfo, UserAdmin) # 第一个参数可以是列表方式二:@admin.register(models.UserInfo) # 第一个参数可以是列表class UserAdmin(admin.ModelAdmin):list_display = ('user', 'pwd',)
ModelAdmin中提供了大量的可定制功能,如
1. list_display,列表时,定制显示的列。
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):list_display = ('user', 'pwd', 'xxxxx')def xxxxx(self, obj):return "xxxxx"
2. list_display_links,列表时,定制列可以点击跳转。
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):list_display = ('user', 'pwd', 'xxxxx')list_display_links = ('pwd',)
3. list_filter,列表时,定制右侧快速筛选。
4. list_select_related,列表时,连表查询是否自动select_related
5. list_editable,列表时,可以编辑的列
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):list_display = ('user', 'pwd','ug',)list_editable = ('ug',)
6. search_fields,列表时,模糊搜索的功能
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):search_fields = ('user', 'pwd')
7. date_hierarchy,列表时,对Date和DateTime类型进行搜索
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):date_hierarchy = 'ctime'
8 inlines,详细页面,如果有其他表和当前表做FK,那么详细页面可以进行动态增加和删除
class UserInfoInline(admin.StackedInline): # TabularInlineextra = 0model = models.UserInfoclass GroupAdminMode(admin.ModelAdmin):list_display = ('id', 'title',)inlines = [UserInfoInline, ]
9 action,列表时,定制action中的操作
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):# 定制Action行为具体方法def func(self, request, queryset):print(self, request, queryset)print(request.POST.getlist('_selected_action'))func.short_description = "中文显示自定义Actions"actions = [func, ]# Action选项都是在页面上方显示actions_on_top = True# Action选项都是在页面下方显示actions_on_bottom = False# 是否显示选择个数actions_selection_counter = True
10 定制HTML模板
add_form_template = None change_form_template = None change_list_template = None delete_confirmation_template = None delete_selected_confirmation_template = None object_history_template = None
11 raw_id_fields,详细页面,针对FK和M2M字段变成以Input框形式
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):raw_id_fields = ('FK字段', 'M2M字段',)
12 fields,详细页面时,显示字段的字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):fields = ('user',)
13 exclude,详细页面时,排除的字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):exclude = ('user',)
14 readonly_fields,详细页面时,只读字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):readonly_fields = ('user',)
15 fieldsets,详细页面时,使用fieldsets标签对数据进行分割显示
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):fieldsets = (('基本数据', {'fields': ('user', 'pwd', 'ctime',)}),('其他', {'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty''fields': ('user', 'pwd'),}),)
16 详细页面时,M2M显示时,数据移动选择(方向:上下和左右)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)
17 ordering,列表时,数据排序规则
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):ordering = ('-id',)或def get_ordering(self, request):return ['-id', ]
18. radio_fields,详细页面时,使用radio显示选项(FK默认使用select)
radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL
19 form = ModelForm,用于定制用户请求时候表单验证
from app01 import models from django.forms import ModelForm from django.forms import fieldsclass MyForm(ModelForm):others = fields.CharField()class Meta:model = models = models.UserInfofields = "__all__"@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):form = MyForm
20 empty_value_display = "列数据为空时,显示默认值"
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin):empty_value_display = "列数据为空时,默认显示"list_display = ('user','pwd','up')def up(self,obj):return obj.userup.empty_value_display = "指定列数据为空时,默认显示"
二. Cookie和Session
1.Cookie和Session的基本介绍
cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。cookie的工作原理是:由服务器产生cookie内容,浏览器收到请求响应后保存在本地;当浏览器再次访问该服务器时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”。简明来说,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”,那么上述的cookie就起到桥接的作用,我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”,然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性,这便出现了session。
cookie的格式:
Set-Cookie: NAME=VALUE;Expires/Max-age=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
参数意义:
- NAME:cookie的名字。
- VALUE:cookie的值。
- Expires:cookie的过期时间。
- Path:cookie作用的路径。
- Domain:cookie作用的域名。
- SECURE:是否只在https协议下起作用。
总结:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。
经过前面的学习我们已经有能力制作一个登陆页面,在验证了用户名和密码的正确性后跳转到后台的页面。但是测试后也发现,如果绕过登陆页面,直接输入后台的url地址也可以直接访问。这个显然是不合理的。其实我们缺失的就是cookie和session配合的验证。有了这个验证过程,我们就可以实现和其他网站一样必须登录才能进入后台页面了。
先说一下这种认证的机制。每当我们使用一款浏览器访问一个登陆页面的时候,一旦我们通过了认证。服务器端就会发送一组随机唯一的字符串(假设是123abc)到浏览器端,这个被存储在浏览器端的东西就叫cookie。而服务器端也会自己存储一下用户当前的状态,比如login=true,username=hahaha之类的用户信息。但是这种存储是以字典形式存储的,字典的唯一key就是刚才发给用户的唯一的cookie值。那么如果在服务器端查看session信息的话,理论上就会看到如下样子的字典
{'123abc':{'login':true,'username:hahaha'}}
因为每个cookie都是唯一的,所以我们在电脑上换个浏览器再登陆同一个网站也需要再次验证。那么为什么说我们只是理论上看到这样子的字典呢?因为处于安全性的考虑,其实对于上面那个大字典不光key值123abc是被加密的,value值{'login':true,'username:hahaha'}在服务器端也是一样被加密的。所以我们服务器上就算打开session信息看到的也是类似与以下样子的东西{'123abc':dasdasdasd1231231da1231231}
借用一张别的大神画的图,可以更直观的看出来cookie和session的关系
cookie和session的应用实例:
<1>先在templates目录下创建两个html,login.html负责登录页面,backend页面代表后台页面
/*---------------------------login.html-----------------------------*/<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><div class="container"><form action="login.html" method="post"><div class="form-group"><label class="sr-only">username</label><input type="text" class="form-control" name="username" placeholder="用户名"/></div><div class="form-group"><label class="sr-only">Password</label><input type="password" class="form-control" name="passwd" placeholder="密码"/></div><div class="form-group"><input class="btn btn-primary" type="submit" value="提交"></div></form> </div> </body> </html>/*---------------------------backend.html-----------------------*/<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><div class="container"><h2>cookie 内容是 {{ cookie_content }}</h2><h2>session 内容是 {{ session_content }}</h2><h2>登录用户名 :{{ username }}</h2></div> </body> </html>
View Code
<2> 在应用下的views.py文件,编写代码逻辑部分
def login(request):print("COOKIES", request.COOKIES)print("SESSION", request.session)#------------首次进入login.html页面cookies和session打印内容#COOKIES {'csrftoken': 'x8OVNJyVE7SMVgPXTLSoJiNNr6KSTG7CyOwXHoKhBKsFwlCyCXh3UVfHExheoA0g', 'sessionid': '9s3jx5sb5euzdla2d1aq44yrehvun1e2'}#SESSION <django.contrib.sessions.backends.db.SessionStore object at 0x00000213ADA15DA0>if request.method == "POST":username = request.POST['username']pwd = request.POST['passwd']print('================================')if username == 'abc' and pwd == '123':#----------------cookie单独使用---------------------#cookie单独使用时,设置cookiea内部字典的内容# ret=redirect('/backend/')# ret.set_cookie("username",username)# return ret#----------cookie和sessions结合使用-----------------# 设置session内部的字典内容request.session['is_login'] = 'true'request.session['username'] = 'abc'#登录成功就将url重定向到后台的urlreturn redirect('/backend/')# 登录不成功或第一访问就停留在登录页面return render(request,'login.html')def backend(request):print("COOKIES", request.COOKIES)print("SESSION", request.session)#-----------------------cookie单独使用------------------# if request.COOKIES.get("username", None):# username = request.COOKIES.get("username", None)# cookie_content = request.COOKIES# return render(request, "backend.html", locals())# #返回值:# # cookie内容是{'username': 'abc'}# # session 内容是# # 登录用户名 :abc#-----------------cookie和session结合使用-----------------"""这里必须用读取字典的get()方法把is_login的value缺省设置为False,当用户访问backend这个url先尝试获取这个浏览器对应的session中的is_login的值。如果对方登录成功的话,在login里就已经把is_login的值修改为了True,反之这个值就是False的"""is_login = request.session.get('is_login', False)# 如果为真,就说明用户是正常登陆的if is_login:# 获取字典的内容并传入页面文件# 或者用if request.session.get("is_login",None):cookie_content = request.COOKIESsession_content = request.sessionusername = request.session['username']return render(request, 'backend.html',{'cookie_content': cookie_content,'session_content': session_content,'username': username})#返回的值:# cookie 内容是 {'csrftoken': 'x8OVNJyVE7SMVgPXTLSoJiNNr6KSTG7CyOwXHoKhBKsFwlCyCXh3UVfHExheoA0g', 'sessionid': '9s3jx5sb5euzdla2d1aq44yrehvun1e2'}# session内容是 < django.contrib.sessions.backends.db.SessionStore object at 0x000001BF7D04DDD8 ># 登录用户名 :abcelse:"""如果访问的时候没有携带正确的session,就直接被重定向url回login页面"""return redirect('/login/')
View Code
<3>编辑urls.py文件,设置函数与页面的绑定关系
from django.contrib import admin from django.urls import path from ORM_Study import views from django.conf.urls import urlurlpatterns = [#path('admin/', admin.site.urls),url('^login/',views.login,name='login'),url('^backend/',views.backend,name='backend'), ]
View Code
<4>最后打开浏览器直接访问/backend/页面,检测是否直接就被重定向到了/login/页面
<5>总结
从上述步骤中我们看到有一下几点:
(1)login页面正确登录的话,后台页面可以获取到浏览器携带的cookie的。
(2)返回的sessionid其实就是cookie值
(3)session的内容是加密的,从客户端获取不到session的内容
(4)服务端可以通过预设的key值取出session的内容并打印到前段
(5)django的session默认是存储在数据库里的,我们可以到数据库查看一下真正session内容,在表Django_session里
(6)session的好处:客户端只有cookie值,始终没有用户信息
(7)session依赖于cookie,cookie保存在浏览器,session保存在服务器端。
<6>cookie和session的知识点总结:
操作cookie:
获取cookie:request.COOKIES[key]设置cookie:response.set_cookie(key,value)
View Code
操作session(session默认在服务器端保存15天):
获取session:request.session[key]设置session:reqeust.session[key] = value删除session:del request.session[key] 设置session时效: request.session.set_expiry(value) * 如果value是个整数,session会在这些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
View Code
>>>>>>>>>待续
转载于:https://www.cnblogs.com/wuxunyan/p/9141018.html
Django:Admin,Cookie,Session相关推荐
- Token ,Cookie、Session傻傻分不清楚?
点击上方蓝色"视学算法",选择"设为星标" 作者 | 王菜鸟1993 来源 | cnblogs.com/JamesWang1993/p/8593494.html ...
- equest,response,session,cookie,application
equest,response,session,cookie,application 觉得写的非常好..很齐全 A:request 客服端向服务器端请求 JAVA讲究封装,所以Request也是某个 ...
- Java Web(三) 会话机制,Cookie和Session详解
很大一部分应该知道什么是会话机制,也能说的出几句,我也大概了解一点,但是学了之后几天不用,立马忘的一干二净,原因可能是没能好好理解这两种会话机制,所以会一直遗忘,一直重新回过头来学习它,今天好好把他总 ...
- 面试被问到:Token ,Cookie、Session傻傻分不清楚?
作者 | 王菜鸟1993 来源 | cnblogs.com/JamesWang1993/p/8593494.html 在做接口测试时,经常会碰到请求参数为token的类型,但是可能大部分测试人员对to ...
- 小白学Django第九天| Cookie和session的那些骚操作
点击上方"JAVAandPython君",选择"星标"公众号 重磅干货,第一时间送达 小白学Django系列: 小白学Django第一天| MVC.MVT以及D ...
- Day 63 django 中间件、cookie、session
Day 63 django 中间件.cookie.session 文章目录 Day 63 django 中间件.cookie.session 1.cookie与session 简介 2.django操 ...
- Python之反爬虫手段(User-Agent,Cookie,Referer,time.sleep(),IP代理池)
现在的爬虫越来越难,各大网站为了预防不间断的网络爬虫,都相应地做出了不同的反爬机制,那么如何能够在不被封IP的情况,尽可能多得爬取数据呢?这里主要介绍到一些通用的反爬措施,虽然不一定适合所有网站,但是 ...
- Day71 分页,cookie and Session
cookie 是保存在客户端的键值对. cookie本身最大支持4096字节,保存在客户端的 session是保存在服务器端的键值对.(依赖cookie) cookie和session cookie的 ...
- 7,复习,多对多表的三种创建,form组件,cookie,session
昨日内容回顾 choices字段 只要是能够罗列出来的有限个选项的都可以使用choices字段来做 1.学历,工作经历,性别,工作状态,客户来源,婚嫁 gender_choices ...
最新文章
- 路径字符串生成树形结构的思路_LeetCode 22. 括号生成
- 【杂项】原来有两种单引号(单引号和反引号)
- 事务里面捕获异常_三问Spring事务:解决什么问题?如何解决?存在什么问题?...
- apache httpclient4 设置超时时间
- java this用法_java中this用法小结
- java对象间的转型,详细讲述Java中的对象转型
- “开源”vs“商业”,差别到底有多大?这篇测试一目了然
- django-索引1909
- 蒙层禁止页面滚动的方案
- 资产信息自动化收集系统 Venux
- 编译原理第三版陈火旺第二章答案
- Html源码在线翻译,HTML – 谷歌翻译网站
- SecureCRT快捷键大全
- sap销售发货的流程_SAP标准业务流程-销售订单处理
- linux安装源文件出现错误,编译安装源码时出现错误的解决方法
- 详解硬件设计中电容电感磁珠
- Oracle 查询一个小时之前表的数据
- 微信小程序地理位置API使用流程
- x:Name与x:Key
- visio2010 去除跨线