zoukankan      html  css  js  c++  java
  • 仿BBS之注册

    模仿BBS的注册功能,先谈一谈项目需求分析

    项目分析
    表设计
    用户表(UserInfo)
    用户电话phone
    用户头像avatar
    用户创建时间create_time


    blog 》》》site 一对一个人站点表

    个人站点表(Blog)
    站点名称site_name
    站点标题site_title
    站点样式site_theme

    文章标签表(Tag)
    标签名称name
    blog >>> Blog 一对多个人站点表

    文章分类表
    分类名称name
    blog >>> Blog 一对多个人站点表

    文章表
    文章标题title
    文章简介desc
    文章详情content
    文章发布时间create_time
    # 数据库查询优化
    文章评论数comment_num
    文章点赞数up_num
    文章点踩数down_num

    blog 》》》 Blog 一对多个人站点表
    tags >>> Tag 多对多标签表
    category 》》》 Category 一对多分类表

    点赞点踩表
    用户名字段user 一对多 个人站点/用户
    文章字段article 一对多 文章表
    点赞点踩is_up 0/1

    文章评论表
    用户名字段user 一对多 个人站点/用户
    文章字段article 一对多 文章表
    评论内容content
    父评论parent(自己跟自己关联) 一对多自身

    models.py文件

    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    class UserInfo(AbstractUser):
        phone = models.BigIntegerField(null=True)
        create_time = models.DateField(auto_now_add=True)
        avatar = models.FileField(upload_to='avatar/',default='avatar/default.png')
        blog = models.OneToOneField(to='Blog',null=True)
    
    class Blog(models.Model):
        site_name = models.CharField(max_length=32)
        site_title = models.CharField(max_length=64)
        theme = models.CharField(max_length=64)
    
    class Category(models.Model):
        name = models.CharField(max_length=64)
        blog = models.ForeignKey(to='Blog',null=True)
    
    
    
    class Tag(models.Model):
        name = models.CharField(max_length=32)
        blog = models.ForeignKey(to='Blog',null=True)
    
    class Article(models.Model):
        title = models.CharField(max_length=64)
        desc = models.CharField(max_length=255)
        content = models.TextField()
        create_time = models.DateField(auto_now_add=True)
        comment_num = models.IntegerField()
        up_num = models.IntegerField()
        down_num = models.IntegerField()
        blog = models.ForeignKey(to='Blog',null=True)
        category = models.ForeignKey(to='Category',null=True)
        tags = models.ManyToManyField(to='Tag',through='Article2Tags',through_fields=('article','tag'))
    
    
    class Article2Tags(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()
    
    
    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)

    我们使用forms组件来限制前后端数据的传输

    forms.py文件

    from django import forms
    from django.forms import widgets
    from app01 import models
    
    class MyForm(forms.Form):
        username = forms.CharField(max_length=8,min_length=3,label='用户名:',error_messages={
            'required':'用户名不能为空',
            'max_length':'用户名最长8位',
            'min_length':'用户名最短3位',
        },widget = 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':'from-control'}))
        confirm_password = forms.CharField(max_length=8,min_length=3,label='确认密码',error_messages={
            'required':'确认密码不能为空',
            'max_length':'确认密码最大8位',
            'min_length':'确认密码最小3位'
        },widget =widgets.PasswordInput(attrs={'class':'form-control'}))
        email = forms.EmailField(label='邮箱',error_messages={
            'required':'邮箱不能为空',
            'invalid':'邮箱格式序错误',
        },widget=forms.widgets.EmailInput(attrs={'class':'form-control'}))
        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
        def clean(self):
            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

    使用views.py视图函数来对路由过来的路径进行匹配执行

    from django.shortcuts import render
    from app01 import myforms
    from app01 import models
    from django.http import JsonResponse
    
    # Create your views here.
    def register(request):
        back_dic= {'code':100,'msg':''}
        form_obj = myforms.MyForm()
        if request.method =='POST':
            form_obj =myforms.MyForm(request.POST)
            if form_obj.is_valid():
                data = form_obj.cleaned_data
                data.pop('confirm_password')
                file_obj = request.FILES.get('myfile')
                if file_obj:
                    data['avatar']= file_obj
                models.UserInfo.objects.create_user(**data)
                back_dic['msg']='注册成功'
                back_dic['url']='/login/'
            else:
                back_dic['code']=101
                back_dic['mag']=form_obj.errors
            return JsonResponse(back_dic)
        return render(request,'register.html',locals())

    我们不妨来看看前端页面经过渲染是什么样子吧

    其实对于用户名,密码以及确认密码和邮箱这种键值对来说我们用ajax来进行交互式时,只是常规操作

    对于头像,我们该怎么如何进行传输呢?

    $('#d1').click(function () {
            $.ajax({
                // 提交的地址,不写默认提交至当前页面,同form表单的action
                url:'/index/',
                // 提交的方式
                type:'post',
                // 提交的数据,一般以键值对的形式出现
                data:{'name':'jason','password':'123'},
                // 回调函数
                success:function (data) {  // data接收的就是异步提交返回的结果
                    alert(data)
                }
            })
        })

    这是常规操作

    <!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>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
        <script src="/static/bootstrap-3.3.7/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 id="myform">
                     {% csrf_token %}
                     {% for form in form_obj %}
                        <div class="form-group">
                            <label for="{{ form.auto_id }}">{{ form.label }}</label>
                            {{ form }}
                            <span class="errors pull-right" style="color:red"></span>
                        </div>
                    {% endfor %}
                </form>
                <div class="form-group">
                    <label for="id_myfile">头像
                        <img src="/static/img/default.png" alt="" width="80" style="margin-left: 20px" id ='id_img'>
                    </label>
                    <input type="file" name="myfile" id="id_myfile" style="display:none">
                </div>
                <button class="btn btn-primary pull-right" id="id_submit">注册</button>
            </div>
        </div>
    
    </div>
    
    <script>
        $('#id_myfile').change(function () {
            let fileObj = this.fiels[0];
            let fileReader= new FileReader()
            fileReader.readAsDataURL(fileObj);
            fileReader.onload = function () {
                $('#id_img').attr('src',fileReader.result)
            }
        });
        $('#id_submit').click(function () {
            let formData = new FormData();
            $.each($('#myform').serializeArray(),function (index, obj) {
                formData.append(obj.name, obj.value)
            });
            formData.append('myfile',$('id_myfile')[0].files[0]);
            $.ajax({
                url:'',
                type:'post',
                data:formData,
                processData:false,
                contentType:false,
                success:function(data){
                    if (data.code==100){
                        location.href=data.url
                    }else{
                        $.each(data.msg,function (index,obj) {
                            let targetId ='#id_'+index;
                            $(targetId).next().html(obj[0].parent().addClass('has-error'))
                        })
                    }
                }
    
            })
        });
        $('input').focus(function () {
            $(this).next().html('').parent().removeClass('has-error')
        })
    </script>
    
    
    
    
    </body>
    </html>

    这是经过Javascript的处理后端h5文件

    在写一个注册页面时,想要实现用户选择头像时,直接就能将选择的头像显示出来,就必须使用到JS的FileReader对象。

    FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。 其中File对象可以是来自用户在一个元素上选择文件后返回的FileList对象(上面提到的使用files属性得到的文件对象),也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果

     可以用window对象的方法查看浏览器对FileReader的支持

    if(window.FileReader) {
         var fr = new FileReader();
         // add your code here
     }
     else {
         alert("Not supported by your browser!");
     }
    承蒙关照
  • 相关阅读:
    定位 -CLGeocoder
    定位
    定位
    定位- 汽车导航
    定位
    SVN
    githubRepository -- 使用
    git 常用指令
    ipad ------ 与iPhone的差别
    总结
  • 原文地址:https://www.cnblogs.com/guanlei/p/11055744.html
Copyright © 2011-2022 走看看