10django
# ajax结合sweetalert(ajax用于页面不刷新也可以提交数据,sweetalert是帮助美化删除二次确认的) 1.下载源码 只需要到dist文件夹内的css和js即可 2.拷贝使用官网提供的案例代码 3.添加配置参数新增等待特效 <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">数据展示</h2> <table class="table table-striped table-hover"> <thead> <tr> <th>主键</th> <th>姓名</th> <th>年龄</th> <th>地址</th> <th>操作</th> </tr> </thead> <tbody> {% for user_obj in user_queryset %} <tr> <td>{{ user_obj.pk }}</td> <td>{{ user_obj.name }}</td> <td>{{ user_obj.age }}</td> <td>{{ user_obj.addr }}</td> <td> <a href="#" class="btn btn-primary btn-xs">编辑</a> <a href="#" class="btn btn-danger btn-xs deleteBtn" delete_id="{{ user_obj.pk }}">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script> (二次确认删除美化过的代码,sweetalert里面有,直接复制过来即可) $('.deleteBtn').click(function () { let $deBtn = $(this); swal({ title: "你确定要删除吗?", text: "你要是真删 就准备好跑路吧!", type: "warning", showCancelButton: true, confirmButtonClass: "btn-danger", confirmButtonText: "牛逼, 准备跑路!", cancelButtonText: "怂货, 我真瞧不起你!", closeOnConfirm: false, closeOnCancel: false, showLoaderOnConfirm: true }, function(isConfirm) { if (isConfirm) { // 编写与后端交互的删除功能 let deleteId = $deBtn.attr('delete_id'); // 发送ajax请求 $.ajax({ url:'', type:'post', data:{'deleteId':deleteId}, success:function (args) { swal(args, "success"); $deBtn.parent().parent().remove() } }) } else { swal("咋又取消了", "你真的怂到家了!", "error"); } }); }) </script>
""" 钩子函数的含义其实就是在程序的执行过程中穿插额外的逻辑 校验用户名是否已存在 钩子函数之局部钩子(校验单个字段) 校验密码和确认密码是否一致 钩子函数之全局钩子(校验多个字段) """ # 局部钩子:校验用户名是否已存在(一次性只能勾一个人) '''钩子函数是数据经过了字段第一层参数校验之后才会执行''' def clean_name(self): # 自动生成的函数名 专门用于对name字段添加额外的校验规则 # 1.先获取用户名 name = self.cleaned_data.get('name') # 2.判断用户名是否已存在 is_exist = models.User.objects.filter(name=name) if is_exist: # 3.提示信息 self.add_error('name', '用户名已存在') # 4.最后将你勾上来的name返回回去 return name # 全局钩子:校验密码与确认密码是否一致(一次性可以勾多个人) def clean(self): # 1.获取多个字段数据 password = self.cleaned_data.get('password') confirm_password = self.cleaned_data.get('confirm_password') if not password == confirm_password: self.add_error('confirm_password', '两次密码不一致 你个傻帽!!!') # 最后将整个数据返回 return self.cleaned_data
min_length 最小长度 max_length 最大长度 label 字段名称 error_messages 错误提示 min_value 最小值 max_value 最大值 initial 默认值 validators 正则校验器 from django.core.validators import RegexValidator phone = forms.CharField( validators=[ RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')], ) widget 控制渲染出来的标签各项属性(比如控制密码是不是密文,姓名是不是文本,用黄色点的部分可以点出来) password = forms.CharField( widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})(比如控制居中) ) forms.widgets.控制type的类型(attrs=控制各项属性:class id ...) choices 选择类型的标签内部对应关系 可以直接编写 也可以从数据库中获取 hobby = forms.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), ) def __init__(self, *args, **kwargs): super(MyForm,self).__init__(*args, **kwargs) self.fields['hobby'].choices = models.Classes.objects.all().values_list('id','caption')
radio select 下拉单选
choicfield 单选框
multiplechoicefield 多选框
checkboxinput 复选框
""" 看源码可以提升编程能力(CBV源码) 也可以从中获取出更多的使用方式(JsonResponse) """ def is_valid(self): return self.is_bound and not self.errors # 查看类源码发现只要给类传参self.is_bound肯定是True @property def errors(self): if self._errors is None: self.full_clean() return self._errors # 查看了源码发现self._errors初始化就是None 所以肯定走full_clean方法 # 查看源码发现校验数据的整个过程内部都有异常处理机制 from django.core.exceptions import ValidationError raise ValidationError('用户名不存在 你个DSB')
forms组件主要配合models里面的默写类一起使用 但是models类里面的字段需要在forms类中相当于重写一遍 代码冗余 为了更好的结合forms与models的关系 有了一个ModelForm(基于forms组件) class MyUser(forms.ModelForm):(类里面再加类,固定写法) class Meta: model = models.User # 指定关联的表 fields = '__all__' # 所有的字段全部生成对应的forms字段 labels = { 'name': '用户名', 'age': '年龄', 'addr': '地址', 'email': '邮箱' } widgets = { "name": forms.widgets.TextInput(attrs={"class": "form-control"}), } def reg(request): form_obj = MyUser() if request.method == 'POST': form_obj = MyUser(request.POST) #form_obj是客户输入的数据 if form_obj.is_valid(): # form_obj.save() # 新增数据 edit_obj = models.User.objects.filter(pk=5).first() #edit_obj指的是要编辑的数据 form_obj = MyUser(request.POST, instance=edit_obj) # 是新增还是保存就取决于有没有instance参数 form_obj.save() # 编辑数据 return render(request, 'reg.html', locals())
# cookie简介 早期的互联网应用程序都是不保存用户状态的,所有人发送请求返回的都是相同的页面 现如今几乎所有的应用程序都可以保存用户状态!!!>>>:如何实现的??? HTTP协议四大特性之一:无状态 让服务端知道你是谁的方式很单一>>>:携带用户名和密码(身份标识) 每次操作之前都需要输入用户名和密码 当你成功登录之后浏览器会在本地帮你保存用户名和密码 每次操作浏览器自动发送用户名和密码 cookie本质 指代服务端让客户端保存的数据(存储在客户端上与用户信息相关的数据) '''简单的记忆:cookie就是存在客户端的东西''' # session简介 早期的cookie是直接存储的用户明文相关信息 不安全 用户登录成功之后 服务端生成一个随机字符串 返回给客户端保存 之后客户端每次发请求携带该随机字符串 服务端获取之后比对后台数据 eg: 服务端 随机字符串1 用户数据1 随机字符串2 用户数据2 随机字符串3 用户数据3 客户端 随机字符串1、随机字符串2、随机字符串3 session本质 指代服务端保存的跟用户信息相关的数据 '''简单的记忆:session就是存在服务端的东西''' """ 1.session的工作必须依赖于cookie 2.客户端也有权拒绝保存数据 """ ps:针对身份标识问题有很多方式 cookie和session是最基本的 token、jwt...
#token简介
token不需要保存数据,用于动态的加密比对(每次把客户输入的东西变成密文和原有的密文做比对,看看是否一致)
# 视图函数返回值 return HttpResonse() return render() return redirect() ... 现在我们不直接返回对象 而是先用变量名指代 然后操作对象方法 (虽然多了这一部,看似没有变化,其实作用很大) res = HttpResonse() return res res = render() return res res = redirect() return res # 基本使用 res.set_cookie(key,value) # 设置 res.COOKIE.get(key) # 获取 # 有很多视图函数需要添加登录认证 有时候又需要取消登录认证 装饰器 # 用户登录之后跳转到用户登录之前想要访问的页面