?
?
?
用户表
客户表
跟进记录表
报名表
缴费记录表
校区表
班级表
课程记录
学习记录表
?
下载 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('没有访问权限,练习管理员')  #效验全部不通过,拒绝请求
原文:https://www.cnblogs.com/haiyang11/p/11688542.html