settings.py
1 # 在项目中要使用到mysql,所以先在settings文件中完成对mysql数据库的配置。 2 DATABASES = { 3 'default': { 4 'ENGINE': 'django.db.backends.mysql', 5 'NAME': 'bbs', 6 'USER':'root', 7 'PASSWORD':'123', 8 'HOST':'127.0.0.1', 9 'PORT':3306 10 } 11 } 12 13 STATIC_URL = '/static/' 14 STATICFILES_DIRS = [ 15 os.path.join(BASE_DIR,'static') # 配置静态文件 16 ] 17 18 AUTH_USER_MODEL = 'app01.UserInfo' # 去
# 在跟settings文件处于同一级别的__init__文件中,完成导入pymysql的配置。
import pymysql
pymysql.install_as_MySQLdb()
myforms.py
1 from django import forms 2 from django.forms import widgets 3 from app01 import models 4 5 6 class MyRegForm(forms.Form): 7 username = forms.CharField(max_length=8, min_length=3, label='用户名', 8 error_messages={ 9 'max_length': '用户名最大八位', 10 'min_length': '用户名最小三位', 11 'required': '用户名不能为空' 12 }, widget=widgets.TextInput(attrs={'class': 'form-control'}) 13 ) 14 password = forms.CharField(max_length=8, min_length=3, label='密码', 15 error_messages={ 16 'max_length': '密码最大八位', 17 'min_length': '密码最小三位', 18 'required': '密码不能为空' 19 }, widget=widgets.PasswordInput(attrs={'class': 'form-control'}) 20 ) 21 confirm_password = forms.CharField(max_length=8, min_length=3, label='确认密码', 22 error_messages={ 23 'max_length': '确认密码最大八位', 24 'min_length': '确认密码最小三位', 25 'required': '确认密码不能为空' 26 }, widget=widgets.PasswordInput(attrs={'class': 'form-control'}) 27 ) 28 email = forms.EmailField(label='邮箱', error_messages={ 29 'required': "邮箱不能为空", 30 'invalid': "邮箱格式错误" 31 }, widget=widgets.EmailInput(attrs={'class': 'form-control'})) 32 33 # 局部钩子 校验用户名是否已存在 34 def clean_username(self): 35 username = self.cleaned_data.get('username') 36 is_user = models.UserInfo.objects.filter(username=username) 37 if is_user: 38 self.add_error('username', '用户名已存在') 39 return username 40 41 # 全局钩子 校验密码是否一致 42 def clean(self): 43 password = self.cleaned_data.get('password') 44 confirm_password = self.cleaned_data.get('confirm_password') 45 if not password == confirm_password: 46 self.add_error('confirm_password', '两次密码不一致') 47 return self.cleaned_data
models.py
from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here. class UserInfo(AbstractUser): # 千万不能放AbstractUser表里有的字段 phone = models.BigIntegerField(null=True) # null=True表示该项可以不填写 # avatar存的是用户头像文件路径 用户上传的头像会自动保存到avatar文件夹下 avatar = models.FileField(upload_to='avatar/',default='avatar/default.jpg') create_time = models.DateField(auto_now_add=True) # 注册时间 blog = models.OneToOneField(to='Blog',null=True) ## 与个人站点处于一对一关系 class Blog(models.Model): # 个人站点表 site_title = models.CharField(max_length=32) # 站点名称 site_name = models.CharField(max_length=32) # 站点名字 site_theme = models.CharField(max_length=255) # 用来存css的文件路径 class Category(models.Model): # 标签表 name = models.CharField(max_length=32) blog = models.ForeignKey(to='Blog') # 与个人站点处于一对多关系 class Tag(models.Model): # 分类表 name = models.CharField(max_length=32) blog = models.ForeignKey(to='Blog') # 与个人站点处于一对多关系 class Article(models.Model): # 文章表 title = models.CharField(max_length=255) desc = models.CharField(max_length=255) # 存小段文本 content = models.TextField() # 存大段文本 create_time = models.DateField(auto_now_add=True) #文章创建时间 # 数据库优化字段 comment_num = models.IntegerField(default=0) # up_num = models.IntegerField(default=0) # 点赞数 down_num = models.IntegerField(default=0) # 点踩数 # 外键字段 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')) class Article2Tag(models.Model): article = models.ForeignKey(to='Article') tag = models.ForeignKey(to='Tag') class UpAndDown(models.Model): # 点赞点踩表 user = models.ForeignKey(to='UserInfo') # 与用户 表形成一对多关系 article = models.ForeignKey(to='Article') # 与文章表形成一对多关系 is_up = models.BooleanField() # 传布尔值 存0/1 用来记录是点赞还是点踩 class Comment(models.Model): # 评论表 user = models.ForeignKey(to='UserInfo') article = models.ForeignKey(to='Article') content = models.CharField(max_length=255) # 评论内容大小 create_time = models.DateField(auto_now_add=True) # 评论时间 parent = models.ForeignKey(to='self',null=True) # 字关联字段
register.html文件
1 <body> 2 <div class="container"> 3 <div class="row"> 4 <div class="col-md-8 col-md-offset-2"> 5 <h2 class="text-center">注册h2> {# 将'注册'进行居中处理 #} 6 <form id="myform" novalidate> 7 {% csrf_token %} 8 {% for foo in form_obj %} {# 直接for循环 #} 9 <div class="form-group"> 10 {#foo.auto_id获取foo渲染的input框的id值#} 11 <label for="{{ foo.auto_id }}">{{ foo.label }}label> 12 {{ foo }} 13 <span class="errors pull-right" style="color: red;">span> 14 div> 15 {% endfor %} 16 <div class="form-group"> {# form-group用来处理输入框之间的间隙 #} 17 <label for="myfile">头像 {# 获取头像,通过input框 #} 18 <img src="/static/img/default.jpg" alt="" height="80" style=" margin-left: 20px" id="img">{# 将img放入label框中,点击图片也可以进行文件选择 margin-left用来调节头像与图片之间的距离#} 20 label> 21 <input type="file" name="avatar" id="myfile" style="display: none"> 22 div> 23 <input type="button" class="btn btn-primary pull-right" value="注册" id="id_submit"> 24 form> 25 div> 26 div> 27 div> 28 29 <script> 30 $('#myfile').change(function () { 31 // 获取用户上传的头像 然后替换到img标签中 32 // 1 获取用户上传的文件对象 33 var fileObj = $(this)[0].files[0]; 34 // 2.利用内置对象FileReader 35 var fileReader = new FileReader(); //文件阅读器 36 // 3.将文件对象交由文件阅读器读取 文件内容 37 fileReader.readAsDataURL(fileObj); // IO操作速度较慢,异步 38 // 4.找到img标签 修改src属性 39 // 等待文件阅读器完全读取完文件数据之后 才做下面的操作 onload 40 fileReader.onload = function(){ $('#img').attr('src',fileReader.result)} 41 }); 42 43 // 绑定点击事件 44 $('#id_submit').click(function () { 45 // 1. 产生内置对象formdata 46 var formData = new FormData(); 47 // 2. 循环添加普通键值对 48 {#console.log($('#myform').serializeArray())#} 49 $.each($('#myform').serializeArray(),function (index,obj) { 50 formData.append(obj.name,obj.value) 51 }); 52 // 3. 手动添加文件 53 formData.append('myfile',$('#myfile')[0].files[0]) ; 54 // 4. 发送ajax请求 55 $.ajax({ 56 url:'', {# url不写,默认往当前页面发送 #} 57 type:'post', 58 data:formData, 59 60 // 传文件需要指定两个参数 61 contentType:false, 62 processData:false, 63 64 success:function (data) { 65 if (data.code==100){ 66 location.href = data.url 67 }else{ 68 // 如果没有成功 说明用户输入的数据不合法 你需要展示错误信息 69 // console.log(data.msg) 70 // 能够将对应的错误信息准确无误的渲染到对应的input下面的span标签中 71 // 手动拼接input的id值 72 $.each(data.msg,function (index,obj) { 73 {#console.log(index,obj)#} 74 var targetId = '#id_' + index; 75 $(targetId).next().text(obj[0]).parent().addClass('has-error') 76 }) 77 } 78 } 79 }) 80 }); 81 82 $('input').focus(function () { 83 $(this).next().text('').parent().removeClass('has-error') 84 }) 85 script> 86 body>