纯音乐mp3,妖种传承者,金牌纨绔
摘要:
补充添加一些字段:
用户电话(phone)bigintegerfield类型
用户头像(avatar)filefield类型(指定上传路径upload_to=‘’,默认头像文件default='avatar/xxx.jpg')
用户创建时间(create_time) datefield类型(设置时间为新增记录时候自动设置为当前时间auto_now_add=true)
一对一关系的blog字段(blog)onetoonefield(to='blog', null=true)
需要知道:用户user会有点赞点踩(upanddown)、评论(comment)、站点(blog)
1、设置静态文件 2、告诉django,自定义创建用户表 3、使用mysql数据库,配置数据库参数 static_url = '/static/' staticfiles_dirs = [ os.path.join(base_dir, 'static'), os.path.join(base_dir, 'app01/static') ] auth_user_model = 'app01.userinfo' databases = { 'default': { 'engine': 'django.db.backends.mysql', 'name': 'bbs01', 'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': '123' } }
# 注意在init文件中写入:
import pymysql
pymysql.install_as_mysqldb()
from django import forms from app01 import models # 创建django的form表单 class myform(forms.form): username = forms.charfield( max_length=8, min_length=3, label='用户名:', error_messages={ 'required': '用户名不能为空', 'max_length': '用户名最大为8位', 'min_length': '用户名最小3位', }, widget=forms.widgets.textinput(attrs={'class': 'form-control'}) ) password = forms.charfield( max_length=8, min_length=3, label='密码:', error_messages={ 'required': '密码不能为空', 'max_length': '密码最大8位', 'min_length': '密码最小3位', }, widget=forms.widgets.passwordinput(attrs={'class': 'form-control'}) ) confirm_password = forms.charfield( max_length=8, min_length=3, label='确认密码:', error_messages={ 'required': '确认密码不能为空', 'max_length': '确认密码最大8位', 'min_length': '确认密码最小3位', }, widget=forms.widgets.passwordinput(attrs={'class': 'form-control'}) ) email = forms.emailfield( label='邮箱:', error_messages={ 'required': '邮箱不能为空', 'invalid': '邮箱格式错误' }, widget=forms.widgets.emailinput(attrs={'class': 'form-control'}) ) # 使用局部钩子和全局钩子对用户名和密码进行二次校验: # 全局钩子校验密码输入是否一致: def clean(self): password = self.cleaned_data.get('password') confirm_password = self.cleaned_data.get('confirm_password') if password != confirm_password: self.add_error('confirm_password', '输入两次密码不一致') return self.cleaned_data # 记得返回 # 局部钩子校验用户名是否存在: def clean_username(self): username = self.cleaned_data.get('username') user_obj = models.userinfo.objects.filter(username=username).first() if user_obj: self.add_error('username', '用户名已存在') return username # 记得返回
from django.db import models from django.contrib.auth.models import abstractuser # create your models here. class userinfo(abstractuser): phone = models.bigintegerfield(null=true) create_time = models.datefield(auto_now_add=true) blog = models.onetoonefield(to='blog', null=true) avatar = models.filefield(upload_to='avatar/', default='avatar/default_avatar.jpg') class blog(models.model): blog_name = models.charfield(max_length=32) blog_title = models.charfield(max_length=64) blog_theme = models.charfield(max_length=64) class article(models.model): title = models.charfield(max_length=64) content = models.textfield() desc = models.charfield(max_length=255) create_time = models.datefield(auto_now_add=true) blog = models.foreignkey(to='blog', null=true) category = models.foreignkey(to='category', null=true) tag = models.manytomanyfield(to='tag', through='article2tag', through_fields=('article', 'tag')) # 优化查询 comment_num = models.integerfield() up_num = models.integerfield() down_num = models.integerfield() class category(models.model): name = models.charfield(max_length=32) blog = models.foreignkey(to='blog', null=true) class article2tag(models.model): article = models.foreignkey(to='article') tag = models.foreignkey(to='tag') class tag(models.model): name = models.charfield(max_length=32) blog = models.foreignkey(to='blog', null=true) class upanddown(models.model): is_up = models.booleanfield() user = models.foreignkey(to='userinfo') article = models.foreignkey(to='article') class comment(models.model): content = models.charfield(max_length=255) create_time = models.datefield(auto_now_add=true) user = models.foreignkey(to='userinfo') article = models.foreignkey(to='article') parent = models.foreignkey(to='self', null=true)
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^register/', views.register) ]
## register.html文件创建:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>title</title> {# <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>#} <script src="/static/jquery-3.4.1.js"></script> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/reg.css"> <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h2 class="text-center">注册页面</h2> <hr> {# 注意:这里使用form表单的目的在于我们需要通过form表单批量处理表单内输入的数据对象#} <form id="myform"> {% csrf_token %} {% for form in form_obj %} {# 通过在input框外套个div,设置div的class包含form-group,#} {# 就可以通过bootstrap的样式来调整input框之间的间距#} <div class="form-group"> <label for="{{ form.auto_id }}">{{ form.label }}</label> {{ form }} <span class="has-error pull-right"></span> </div> {% endfor %} </form> <div class="form-group"> <label for="id_myfile"> <img id="id_avatar" src="/static/avatar/default_avatar.jpg" width="70" class="img-thumbnail"> </label> 点击图片上传头像 <input type="file" id="id_myfile" name="myfile" class="hide"> </div> <button class="btn btn-primary pull-right" id="id_submit">提交注册</button> </div> </div> </div> <script> // 将用户上传的图片文件即时渲染到该页面显示 $('#id_myfile').on('change',function () { // 获取上传文件对象 let file_obj = this.files[0]; // 生成一个内置对象 let filereader = new filereader(); // 把文件对象传给内置对象 filereader.readasdataurl(file_obj); // 将读取出的文件对象替换到img标签 // 因为渲染图片的速度远比文件阅读器读取文件的速度 // 所以,这里需要用onload方法等待文件阅读器读取完毕之后在渲染图片,图片才会显示 filereader.onload = function () { $('#id_avatar').attr('src', filereader.result) } }) // 通过ajax发送请求,提交数据 $('#id_submit').on('click',function () { // ajax无法传自己传文件,需要借助内置对象formdata传文件 // 声明一个formdata对象,formdata对象既能传文件又可以传普通键值,通过append的方式添加 let formdata = new formdata(); // jquery对象方法each方法: // 将通过$('#myform').serializearray()方法得到的json格式的对象数组遍历它每个键值对 // 把遍历出来的每个键值对通过函数处理,function()中的index是遍历出来的键值对加的索引, // obj就是遍历出来的键值对(也就是这里form表单里面input框的name和填写的value) $.each( // 通过serializearray() 方法序列化form表单值来创建对象数组(名称和值),该方法返回的是个json对象 // 返回的 json 对象是由一个对象数组组成的,其中每个对象包含键值对 name和value $('#myform').serializearray(), function (index, obj) {formdata.append(obj.name,obj.value);} // 1 {name: "username", value: "sgt"} 对应的index 和 obj ); // function函数内将遍历出来的json数据通过点name和点value得到对应键值添加进formdata中 // 普通键值(input框填入的键值)添加完毕,接下来添加文件数据到formdata中 formdata.append('myfile', $('#id_myfile')[0].files[0]); $.ajax({ url: '', // 不写默认当前页面路由提交 type: 'post', // post提交方式 data: formdata, // 传数据和文件就得借助内置对象formdata发送请求 processdata: false, // 告诉浏览器不对数据做任何处理 contenttype: false, // 不进行任何编码,formdata数据对象django后端能够识别 // 接下来 success:function (data) { // 注册成功,跳转到后端传来的指定页面 if (data.code==100) {location.replace(data.url)} // 注册失败,将后端传来的校验不成功的提示信息进行处理渲染到前端 // 这里需要注意一点:django的form表单在前端渲染的时候会将每个input框的id名按规律 // 定义名字,比如像这样:id_username、id_password else { $.each( data.msg, function (index, obj) { // 注意:index obj 分别是:username ["用户名最小3位"] // 和上面的方法不一样,这个是将字典使用each方法,上面是将数组使用each方法 let targetid = '#id_'+index; // 拼接出input框的id名 // 遍历出来的每个字段名字,通过上面拼接的对应input框对应的id名,通过这个 // id名字就能找到它,它下面(通过next()方法)就是我们需要处理的span标签 // 将它添加html文本(就是错误提示信息,注意obj是个列表),同时继续链式操作 // 让错误的input框标红框,警告提示,通过parent()方法找到父标签div,将其 // class加入一个has-error即可达到目的 $(targetid).next().html(obj[0]).parent().addclass('has-error') } ) } } }) }); // 上面通过ajax发送post请求进行注册过程基本全部完成,最后还实现了错误信息的渲染,此时还需进行完善一下 // 用户如果注册一次提示错误,继续进行注册的话,就需要再次清空错误提示,所以: $('input').on('focus',function () { $(this).next().html('').parent().removeclass('has-error') // 方法同上面加入错误信息类似,也是找到input框下面的span标签,将她的html置空,就去掉了红色提示 // 同时继续找到其父标签div去掉class里面的has-error,红框提示取消 }) </script> </body> </html>
## views.py视图函数
from django.shortcuts import render,httpresponse,redirect from app01.myform.myform import myform from app01 import models from django.http import jsonresponse # create your views here. def register(request): form_obj = myform() # 先定义一个响应字典,后面注册请求来了返回时候要使用 back_dic = {'code': 100, 'msg': ''} if request.method == 'post': # 将register页面提交的普通数据获取到丢给myform(),实例化一个form_obj form_obj = myform(request.post) # 通过form_obj得到django自动校验提交表单处理结果 if form_obj.is_valid(): # 校验通过,获取到通过的所有键值数据字典 data = form_obj.cleaned_data # 这里需要注意,字典里面有个confirm_password的键值,这个键值在校验通过后是不需要的 # 所以需要去掉: data.pop('confirm_password') # 获取用户上传的头像文件对象 file_obj = request.files.get('myfile') # 这里需要加一层判断,看看用户在前端是否上传了头像文件,还是用的默认头像 # 传了就添加进data,没传就直接新增数据 if file_obj: # 用户上传了头像文件,往data里添加头像文件的键值 data['avatar'] = file_obj # 注意要用create_user才能正常创建用户数据 # data是字典形式的键值对,直接打散传入,perfect! models.userinfo.objects.create_user(**data) back_dic['msg'] = '注册成功' # 在相应数据字典里添加注册成功后跳转的页面路由 back_dic['urs'] = '/login/' # 校验不通过,注册不成功 else: back_dic['code'] = 101 # 用101代表注册失败 # 将校验失败的信息字典传进去,等待前端渲染提示用户注册失败 back_dic['msg'] = form_obj.errors return jsonresponse(back_dic) return render(request, 'register.html', locals())
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
新手学习Python2和Python3中print不同的用法
Python基于os.environ从windows获取环境变量
网友评论