标签:contain widgets 需要 port 排除 mode iss 登陆 digest
?
?
?
用户表
客户表
跟进记录表
报名表
缴费记录表
校区表
班级表
课程记录
学习记录表
?
下载 pip install django-multiselectfield
?
views
from django.shortcuts import render,redirect,HttpResponse
from crm import models
import hashlib
def login(request):
if request.method == 'POST':
user = request.POST.get('username')
pwd = request.POST.get('password')
md5 = hashlib.md5() #将密码加密验证
md5.update(pwd.encode('utf-8'))
pwd = md5.hexdigest()
obj = models.UserProfile.objects.filter(username=user,password=pwd,is_active=True).first()
if obj: #obj查询没有结果为none
return redirect('crm:customer')
return render(request, 'login.html',{'error':'用户名密码错误'})
return render(request,'login.html')
from django import forms #forms组件
from django.core.exceptions import ValidationError
class RegForm(forms.ModelForm):
password = forms.CharField(min_length=6,widget=forms.PasswordInput(
attrs={'placeholder':'密码','autocomplete':'off'})) #自定义会覆盖默认的
re_password = forms.CharField(min_length=6,widget=forms.PasswordInput(
attrs={'placeholder':'确认密码','autocomplete':'off'})) #新增字段
class Meta: #生成默认字段
model = models.UserProfile
fields = '__all__' #所有字段在前端展示form组件,所有字段使用['username','password']
exclude = ['is_active'] #排除字段,生成时候没有,默认使用数据库中的默认值
widgets={ #默认字段对应的插件,添加属性
'username':forms.TextInput(attrs={'placeholder':'用户名','autocomplete':'off'}),
'password':forms.PasswordInput(attrs={'placeholder':'密码','autocomplete':'off'}),
'name':forms.TextInput(attrs={'placeholder':'真是姓名','autocomplete':'off'}),
'mobile':forms.TextInput(attrs={'placeholder':'手机号','autocomplete':'off'}),
}
error_messages={
'username':{
'unique':'用户名相同重新输入'
}
}
def clean(self): #全局钩子
self._validate_unique = True #到数据库效验唯一性,前端会展示数据已经存错误
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
#判断两次密码是否一致,是将数据返回,and前面为判断是否为空
if password and password == re_password:
md5 = hashlib.md5()
md5.update(password.encode('utf-8'))
self.cleaned_data['password'] = md5.hexdigest() #将密码修改为加密后的
return self.cleaned_data
self.add_error('re_password','两次密码不一致!') #加入到指定字段显示错误
raise ValidationError('两次密码不一致')
def reg(request): #注册账号
form_obj = RegForm() #实例化对象
if request.method == 'POST':
form_obj = RegForm(request.POST)
# print(form_obj)
if form_obj.is_valid(): #获取form表单进行效验
form_obj.save()
return redirect('crm:login') #数据写入后完,跳转至登录页面
# print(form_obj.cleaned_data)
return render(request,'reg.html',{'form_obj':form_obj})
?
login.html
<form action="" method="post">
{% csrf_token %}
<div>
<input type="text" name="username" class="username" placeholder="输入账号" autocomplete="off">
</div>
<div>
<input type="password" name="password" class="password" placeholder="输入密码" oncontextmenu="return false"
onpaste="return false">
</div>
<div>{{ error }}</div>
<button id="submit" >登录</button>
</form>
?
展示方法
普通字段
#对象.字段名 ——》 数据库的值
<td>{{ customer.qq }}</td>
?
choices
#对象.字段名 ——》 数据库的值
#对象.get_字段名_display() ——》 对应显示的值
<td>{{ customer.get_source_display }}</td>
?
外键
#对象.外键 ——》 关联的对象 __str__
#对象.外键.字段
<td>{{ customer.consultant.name }}</td> #consultant外键
?
多对多
<td>{% for foo in customer.class_list.all %}
{{ foo.get_course_display }}
{% endfor %}
</td>
?
自定义model方法
from django.utils.safestring import mark_safe #前端html不转义
#前端调用:
<td>{{ customer.show_status }}</td>
#models
def show_status(self):
color_dict = {
'signed': 'green',
'unregistered':'red',
'studying': 'pink',
'paid_in_full':'gold'
}
return mark_safe(f'<span style="color: white;background-color: {color_dict.get(self.status)};padding: 3px">{self.get_status_display()}</span>')
Q((Q(qq__contains=query) | Q(name__contains=query) )
q = Q()
q.connector = 'OR'
q.children.append(Q(qq__contains=query))
q.children.append(Q(name__contains=query))
Q(qq__contains=query) Q(('qq__contains',query))
request.GET QueryDict 默认不可修改
request.GET._mutable = True
request.GET['page'] = 1
QueryDict(mutable=True) 可修改的字典
request.GET.copy() 深拷贝 可修改
request.GET.urlencode() {query:123,page:2} _> query=123&page=2
生成url地址
@register.simple_tag
def url_tag(request,name,*args,**kwargs):
url = reverse(name,args=args,kwargs=kwargs)
next = request.get_full_path()
qd = QueryDict(mutable=True)
qd['next']=next
return "{}?{}".format(url,qd.urlencode())
编辑保存后跳转到原页面
next = request.GET.get('next')
if next:
return redirect(next)
return redirect('crm:customer_list')
?
用户登录成功,查询权限信息,也就是查询权限路径
#去空去重
permissions = user_obj.roles.filter(permissions__url__isnull=False).values('permissions__url').distinct()
#user_obj.roles permissions__url
#获取到的是当前登录成功的用户对象,通过用户对象,找到用户角色,在用双下方法查找当前url权限有多少
?
将路径信息保存在session中
#query_set默认不可json序列化
request.session['permissions'] = list(permissions)
#登录状态保存在session中
request.session['is_login'] = True #保存登录状态
?
获取页面路径,进行效验:
class RbacMiddleWare(MiddlewareMixin):
def process_request(self,request):
url = request.path_info #获取当前访问的地址
for i in settings.WHITE_LIST: #白名单校验,判断url中是否含有login
if re.match(i,url): #i正则匹配url是否跟自己匹配
return
is_login = request.session.get('is_login') #没有登录状态,重新登录
if not is_login:
return redirect('login')
for i in settings.PASS_AUTH_LIST: #免认证登录,不需要权限,如首页
if re.match(i,url):
return
permissions = request.session.get('permissions') #获取权限信息
for i in permissions: #判断访问的地址是否跟权限中地址匹配成功
if re.match(r'^{}$'.format(i['permissions__url']), url):
return
return HttpResponse('没有访问权限,练习管理员') #效验全部不通过,拒绝请求
标签:contain widgets 需要 port 排除 mode iss 登陆 digest
原文地址:https://www.cnblogs.com/haiyang11/p/11688542.html