zoukankan      html  css  js  c++  java
  • BBS之注册与登录

    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>
  • 相关阅读:
    建议自学
    大牛之术
    学习榜样
    .net源码
    练习题
    学习-如何克服拖延
    如何解决困难问题
    最近阅读
    如何学习一门新语言
    安全问题关注博客
  • 原文地址:https://www.cnblogs.com/blue-tea/p/11595640.html
Copyright © 2011-2022 走看看