一. 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 = 3
date_hierarchy ="date"
admin.site.register(book,MyAdmin)

<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): # TabularInline
extra = 0
model = models.UserInfo class 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 fields class MyForm(ModelForm):
others = fields.CharField() class Meta:
model = models = models.UserInfo
fields = "__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.user
up.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>

<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 == '':
#----------------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重定向到后台的url
return 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.COOKIES
session_content = request.session
username = 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 >
# 登录用户名 :abc
else:
"""
如果访问的时候没有携带正确的session,
就直接被重定向url回login页面
"""
return redirect('/login/')

<3>编辑urls.py文件,设置函数与页面的绑定关系

from django.contrib import admin
from django.urls import path
from ORM_Study import views
from django.conf.urls import url urlpatterns = [
#path('admin/', admin.site.urls),
url('^login/',views.login,name='login'),
url('^backend/',views.backend,name='backend'),
]

<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)

 操作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失效策略。

>>>>>>>>>待续

Django:Admin,Cookie,Session的更多相关文章

  1. Java Web(三) 会话机制,Cookie和Session详解

    很大一部分应该知道什么是会话机制,也能说的出几句,我也大概了解一点,但是学了之后几天不用,立马忘的一干二净,原因可能是没能好好理解这两种会话机制,所以会一直遗忘,一直重新回过头来学习它,今天好好把他总 ...

  2. Java Web(三) 会话机制,Cookie和Session详解(转载)

    https://www.cnblogs.com/whgk/p/6422391.html 很大一部分应该知道什么是会话机制,也能说的出几句,我也大概了解一点,但是学了之后几天不用,立马忘的一干二净,原因 ...

  3. Asp.net 中ViewState,cookie,session,application,cache的比较

    Asp.net 中的状态管理维护包含ViewState,cookie,session,application,cache五种方式,以下是它们的一些比较: 1.存在于客户端还是服务端 客户端: view ...

  4. Token ,Cookie和Session的区别

    在做接口测试时,经常会碰到请求参数为token的类型,但是可能大部分测试人员对token,cookie,session的区别还是一知半解. Cookie cookie 是一个非常具体的东西,指的就是浏 ...

  5. 彻底弄懂session,cookie,token

    session,cookie和token究竟是什么 简述 我在写之前看了很多篇session,cookie的文章,有的人说先有了cookie,后有了session.也有人说先有session,后有co ...

  6. Token ,Cookie、Session傻傻分不清楚?

    作者 | 王菜鸟1993 来源 | cnblogs.com/JamesWang1993/p/8593494.html 在做接口测试时,经常会碰到请求参数为token的类型,但是可能大部分测试人员对to ...

  7. QQ浏览器、搜狗浏览器等兼容模式下,Asp.NetCore下,Cookie、Session失效问题

    原文:QQ浏览器.搜狗浏览器等兼容模式下,Asp.NetCore下,Cookie.Session失效问题 这些狗日的浏览器在兼容模式下,保存Cookie会失败,是因为SameSiteMode默认为La ...

  8. web开发(三) 会话机制,Cookie和Session详解

    在网上看见一篇不错的文章,写的详细. 以下内容引用那篇博文.转载于<http://www.cnblogs.com/whgk/p/6422391.html>,在此仅供学习参考之用. 一.会话 ...

  9. 会话机制,Cookie和Session详解

    转载自:https://www.cnblogs.com/whgk/p/6422391.html 很大一部分应该知道什么是会话机制,也能说的出几句,我也大概了解一点,但是学了之后几天不用,立马忘的一干二 ...

  10. session,cookie,jwt的简单使用

    cookie的使用 https://blog.csdn.net/qq_58168493/article/details/122492358 session的使用 https://blog.csdn.n ...

随机推荐

  1. springMVC @ModelAttribute功能

    @ModelAttribute功能:将数据模型回写到页面 如: public String validate(@Valid @ModelAttribute("user") User ...

  2. 使用大白菜U盘进入PE后再次重启电脑会留后门的清理方法

    使用大白菜U盘进入PE后再次重启电脑会留后门,这个后门主要是自动下载安装一些软件,比如金山毒霸等. 清除方法: 1.每次用完PE重启前,清理以下地方: ①c:\Windows\xxxxx.exe(查看 ...

  3. windows下本地安装oracle忘记密码,账号被锁咋办

    忘记密码咋办: 进入cmd,输入set ORACLE_SID=ymxg  (ORACLE_SID的值为你想登录的oracle实例的SID) 然后输入:sqlplus / as sysdba 最后输入: ...

  4. With Storm Spouts, when is declareOutputFields( ) called?

    The method IComponent.declareOutputFields(...) is called on the client machine when the client code ...

  5. CSS3 timing-function: steps()介绍

    在应用 CSS3 渐变/动画时.有个控制时间的属性 <timing-function>.它的取值中除了经常使用到的三次贝塞尔曲线以外,还有个steps() 函数. steps 函数指定了一 ...

  6. Notepad++ 设置执行 lua 和 python

    Notepad++ 设置执行 lua 和 python 一.设置 run -> 设置 cmd /k lua "$(FULL_CURRENT_PATH)" & PAUS ...

  7. Android中验证输入是否为汉字及手机号,邮箱验证,IP地址可用port号验证

    1,验证是否为汉字 // 验证昵称 private boolean verifyNickname() { String nickname = edt_username.getText().toStri ...

  8. PHP图像操作类

    基于已给出的各种图像操作方法,这里我总结出了PHP图像操作的一个类,包含给图像加入文字水印.图像水印和压缩图片. 读者可自行加入功能. <? php class Image { private ...

  9. MEAN框架介绍

    近期在Angular社区的原型开发人员间.一种全Javascript的开发架构MEAN正突然流行起来.其首字母分别代表的是:(M)ongoDB--NoSQL的文档数据库,使用JSON风格来存储数据,甚 ...

  10. nyoj--102--次方求模(快速幂)

    次方求模 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 求a的b次方对c取余的值 输入 第一行输入一个整数n表示测试数据的组数(n<100) 每组测试只有一行,其 ...