Tips: 工欲善其事,必先利其器。我们做Password验证的时候绝壁不可能使用铭文进行验证。 再Django中我们可以采用Django.contrib.auth.hasher.make_password将密码加密。再admin保证铭文注册存储密文,可以采用models下模型重写save达到效果。
最后强调一点, 如果不想用csef直接在settings的中间件中将其删除即可。
Task15 Deemo Login
密码的检验,可以用Django.contrib.auth.hasher.check_password进行检查.登陆之后我们使用session存储用户信息到缓存中同时用户自身也存储信息(cookie) ,之后再登录得时候既可以验证了
# 首先是新建一个有password的model
class Player(models.Model):
name = models.CharField(verbose_name='昵称', max_length=10, blank=False, null=False)
password = models.CharField(verbose_name='密码', max_length=100, blank=False, null=False)
have_game = models.ManyToManyField(Gammer)
plant = models.ForeignKey(GamePlant, on_delete=models.PROTECT)
objects = User_password_update()
# 覆写save方法 方便password的加密
def save(self):
self.password = make_password(self.password)
super().save()
class Meta:
db_table = 'player'
verbose_name = '玩家信息'
verbose_name_plural = verbose_name
# 覆写object update过滤器 同样是为了方便加密
class User_password_update(models.Manager):
def update(self, **kwargs):
password = kwargs['password']
if '_sha256' not in password:
kwargs['password'] = make_password(password)
super().update(**kwargs)
# views的登录(一个比较详细的登录过程)
@csrf_exempt
def login(request: HttpRequest):
if request.method == 'POST':
login_id = request.POST.get('id', '')
login_pwd = request.POST.get('pwd', '')
# 从实际的角度除法,其实这样的判断应该放在前端的
if login_pwd == '' or login_id == '':
return HttpResponse('没有添加参数,请刷新重试')
else:
try:
player = Player.objects.get(id=int(login_id))
except BaseException as e:
return HttpResponse('不存在id为', login_id, '的用户')
if check_password(login_pwd, player.password):
# 设置我们的session
request.session['login_user'] = {
# 这里应该缓存中生出来的编码,但是我就不生成了,我直接定西反正用户只有一个
'user': 'wangzhihuan'
}
return show_Games()
#return redirect('')
else:
return HttpResponse('登录失败')
else:
return HttpResponse('访问方式失败,怀疑是爬虫,你个机器人耗子为汁')
可以看到cookie 中设置了session.在接下来只要进行session的判断即可,我这里没有搞感兴趣的可以搞一下
Task16 路由配置
在上面我们也讲过, Django一共分两个路由,主路由(django-prioject-url)和子路由(django-app-url)
子路由使用需要再主路由中注册(path(include()))
--------------------------------上面属于是咱们Task1 就会的东西了---------
咱们知道,url的配置咋写:
urlpatterns = [ path('model/', model_try),
# 子目录
path('son/', include('test1.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# 但实际上, url path应该这么写:
app_name = 'game'
urlpatterns = [ path('model/', model_try, name = None),
# 子目录
path('son/', include('game.urls'),name_space = 'game')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
也就是说,我们还没有部署项目的时候我们不需要用到name, namespace这两个参数。这两个参数在反向解析中使用
问题又来了,什么是反向解析,反向解析有什么用处?
首先是普通的,或者说正向解析的过程:客户端的浏览器发起了一个url请求, Django根据正则结果返回相应views.
那反向解析,顾名思义就是正向反过来,透过一个views的名字再结合request的参数与值反过来得到url的结果,再跟据url进行正向解析返回结果。使用场景不如说登录或跳转到那个,如我们上面可以使用的return redirect(’’), 里面的参数就可以是我们的命名。简单的概念可以从这篇博客中获取https://www.cnblogs.com/ssgeek/p/13200526.html
Tips:
- 在总路由给子路由赋值namespace字段的时候,一定要app_name引入你的子路由所属的app的位置。(声明子路由)
- 可以在HTML中使用,用来减小修改path得工作量:<a href = “{% url ‘game:login’ val1 val2%}”
- 在我们得views中进行重定向(redirect/ HttpResponseRedirect)
同时众所周知,再Django中url的解析时使用正则表达式进行分配,所以我们可以用正则的方式进行url的写。当然,Django1的保留产物我们就不看了,直接看path方法,也为后面的restful打下一小步基础。
换句话说就是: path(‘url//’)