BBS仿博客园 表分析 注册功能的实现

一、表分析

存在7张表 :

用户表UserInfo

站点表Blog

标签表Tag

分类表Category 

点赞表 UpAndDown

评论表 Comment

文章表 Article


用户表 UserInfo 继承django自带的auth组件里的user 表 用户电话 phone 用户头像 avatar 创建时间 create_time
blog 一对一



站点表 Blog 站点名 name 标题 title 主题 theme 存放html样式


标签表Tag 标签名 name blog 一对多 atricle 多对多 创建第三张表,可以实现添加字段的功能



分类表 Category 类名 name blog 一对多


点赞表 UpAndDown
点赞与否 is_up user 一对多 article 一对多


评论表 Comment 内容 content 评论时间 create_time user 一对多 article 一对多 parent 对自己 考虑到对作者评论,对其他用户评论

 

models.py

from django.db import models


from django.contrib.auth.models import AbstractUser


class UserInfo(AbstractUser):
    phone = models.BigIntegerField()
    create_time = models.DateField(auto_now_add=True)
    # 该字段会将接受到文件自动存放到avatar文件夹下,只存该文件的路径 比如:avatar/111.png
    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=32)
    # 站点的样式,存放其对应的文件路径
    site_theme = models.CharField(max_length=64)


class Tag(models.Model):
    name = models.CharField(max_length=16)
    blog = models.ForeignKey(to='Blog', null=True)


class Category(models.Model):
    name = models.CharField(max_length=16)
    blog = models.ForeignKey(to='Blog', null=True)


class Article(models.Model):
    title = models.CharField(max_length=32)
    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='Article_Tag', through_fields=('article', 'tag'))


class Article_Tag(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)

  

自定义form组件实现输入信息的初步校核

myform.py

from django import forms
from django.forms import widgets
from app01 import models

class MyForm(forms.Form):
    username = forms.CharField(max_length=12, min_length=4, label='用户名',
                               widget=widgets.TextInput(attrs={'class': 'form-control'}), error_messages={
            'max_length': '用户名长度最多不超过12位',
            'min_length': '用户名长度最短不低于4位',
            'required': '用户名不能为空'
        })

    password = forms.CharField(max_length=12, min_length=4, label='密码',
                               widget=widgets.PasswordInput(attrs={'class': 'form-control'}), error_messages={
            'max_length': '密码长度最多不超过12位',
            'min_length': '密码长度最短不低于4位',
            'required': '密码不能为空'
        })
    re_password = forms.CharField(max_length=12, min_length=4, label='确认密码',
                                  widget=widgets.PasswordInput(attrs={'class': 'form-control'}), error_messages={
            'max_length' : '确认密码长度最多不超过12位',
            'min_length': '确认密码长度最短不低于4位',
            'required': '确认密码不能为空'
        })
    email = forms.EmailField(label='邮箱',widget=widgets.EmailInput(attrs={'class':'form-control'}) ,error_messages={
        'required':'邮箱不能为空',
        'invalid': '邮箱格式不正确'
    })
    phone = forms.IntegerField(label='手机号码',widget=widgets.PasswordInput(attrs={'class': 'form-control'}),error_messages={
        'invalid':'请输入正确的手机号码',
        'required':'手机号码不能为空'

    })

    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')
        re_password = self.cleaned_data.get('re_password')
        if password != re_password:
            self.add_error('re_password','两次密码不一致!')
        return self.cleaned_data

  

view.py 下的register 

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
from app01 import myform
from app01 import models
from django.http import JsonResponse



def register(request):
    back_dic = {'code':100,'msg':''}
    form_obj = myform.MyForm()
    if request.method == 'POST':
        form_obj = myform.MyForm(request.POST)
        if form_obj.is_valid():
            data = form_obj.cleaned_data
            #将re_password 去掉
            data.pop('re_password')
            #获取用户上传的文件对象
            file_obj = request.FILES.get('myfile')
            #判断用户是否上传了头像
            if file_obj:
                #往data里添加一组键值
                data['avatar'] = file_obj
            models.UserInfo.objects.create_superuser(**data)
            back_dic['msg'] = '注册成功'
            back_dic['url'] = '/login/'
        else:
            back_dic['code'] = 101
            back_dic['msg'] = form_obj.errors
        return JsonResponse(back_dic)
    return render(request,'register.html',locals())

  

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>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3" style="color: #4cae4c">
            <h2 class="text-center">注册页面</h2>
            <form novalidate id="myform" >
                {% csrf_token %}
                <div class="form-group">
                    {% for foo in form_obj %}
                        <label for="{{ foo.auto_id }}" style="margin-top: 10px">{{ foo.label }}</label>
                        {{ foo }}
                        <span class="error pull-right" style="color: #ff7090;margin-top: 10px" ></span>
                    {% endfor %}
                </div>

            </form>
            <div class="form-group">
                <label for="id_myfile">大头贴
                    <img src="/static/img/default.png" alt="" width="80px" style="margin-left: 20px" id="id_img">
                </label>
                <input type="file" name="myfile" id="id_myfile" style="display: none">
            </div>
            <button class="btn btn-success pull-right" id="id_submit">注册</button>
        </div>
    </div>
</div>

<script>
    $('#id_myfile').change(function () {
       {#获取上传的文件对象#}
        let file_obj = this.files[0];
        {#生成一个内置对象#}
        let fileReader = new FileReader();
        {#将文件对象传递给内置对象#}
        fileReader.readAsDataURL(file_obj);
        {#将读取出的文件对象替换到img标签#}
        fileReader.onload = function () {
            {#等待文件阅读器读取完毕再渲染图片#}
            $('#id_img').attr('src',fileReader.result)
        }
    });

    {#ajax提交数据#}
    $('#id_submit').click(function () {
        {#生成一个Formdata对象#}
        let formData = new FormData();
        {#往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 (datas) {
                if (datas.code == 100){
                    {#跳到登陆页面#}
                    location.href = datas.url
                }else{
                    $.each(datas.msg,function (index,obj) {
                        let targetId = '#id_' + index;  {#id_username,id_password#}
                        $(targetId).next().html(obj[0]).parent().addClass('has-error')
                    })
                }
            }
        })
        
    });
    $('input').focus(function () {
        $(this).next().html('').parent().removeClass('has-error')
    })

</script>

</body>
</html>

  

初步效果:

 

 

 

 

 

 

 

 

 

 

  

 

  

 

  

 

  

 

  

 

posted on 2019-06-19 21:59  michael-chang  阅读(285)  评论(0编辑  收藏  举报

导航