首页 > 其他 > 详细

bbs 注册功能

时间:2019-06-19 21:59:43      阅读:56      评论:0      收藏:0      [点我收藏+]

标签:创建时间   eth   b-   json   attrs   python   拼接   orm   http   

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 is_up
1 1 1
2 1 0
1 2 0


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

user article content parent
1 1 666
1 2 888
2 1 666
技术分享图片
 1 from django.db import models
 2 
 3 # Create your models here.
 4 from django.contrib.auth.models import AbstractUser
 5 
 6 
 7 
 8 class UserInfo(AbstractUser):
 9 
10     phone = models.BigIntegerField(null=True)
11     create_time = models.DateField(auto_now_add=True)
12     #文件存放的路径,avatar,自动给你创这个文件夹,默认头像
13     #如果用户上传了一个头像,就会把这个文件放到avatar这个文件夹下面,如果不上传头像我就用默认的这个
14     avatar = models.FileField(upload_to=avatar/,default=static/img/default.jpg)
15     blog = models.OneToOneField(to=Blog,null=True)  #null=True 可以不写,不要样式什么的
16 
17 #个人站点
18 class Blog(models.Model):
19     site_name = models.CharField(max_length=32)
20     site_title = models.CharField(max_length=64)
21     #存css样式文件的样式
22     theme = models.CharField(max_length=32)
23 
24 class Category(models.Model):
25     name = models.CharField(max_length=32)
26     blog = models.ForeignKey(to=Blog)
27 
28 class Tag(models.Model):
29     name = models.CharField(max_length=32)
30     blog = models.ForeignKey(to=Blog)
31 
32 class Article(models.Model):
33     title = models.CharField(max_length=32)
34     desc = models.CharField(max_length=256)
35     #存大段文本
36     content = models.TextField()
37     create_time = models.DateField(auto_now_add=True)
38     #文章的评论数,点赞数,点踩数
39     comment_num = models.IntegerField(default=0)
40     up_num = models.IntegerField(default=0)
41     down_num = models.IntegerField(default=0)
42     blog = models.ForeignKey(to=Blog,null=True)
43     category = models.ForeignKey(to=Category,null=True)
44     tag = models.ManyToManyField(to=Tag,through=Article2Tag, through_fields=(article,tag)) #文章的标签
45 
46 #自创的第三张表
47 class Article2Tag(models.Model):
48     article = models.ForeignKey(to=Article)
49     tag = models.ForeignKey(to=Tag)
50 
51 class UpAndDown(models.Model):
52     user = models.ForeignKey(to=UserInfo)
53     article = models.ForeignKey(to=Article)
54     #存0,1
55     is_up = models.BooleanField()
56 
57 
58 
59 class Comment(models.Model):
60     user = models.ForeignKey(to=UserInfo)
61     article = models.ForeignKey(to=Article)
62     content = models.CharField(max_length=128)
63     create_time = models.DateField(auto_now_add=True)
64     parent = models.ForeignKey(to=self,null=True)
models.py

注意(默认值设计):

UserInfo表需要注意的(默认值):

1.phone =models.BigIntegerField(null=True)

2.create_time=models.DateField(auto_now_add=True)

3.blog = models.OneToOneField(to=‘Blog‘,null=True)  可以不要样式

Article表

1.create_time = models.DateField(auto_now_add=True)

2.blog = models.ForeignKey(to=‘Blog‘,null=True)

3.category = models.ForeignKey(to=‘Category‘,null=True)

4.content = models.TextField() #存大段文本

Comment表

1.create_time = models.DateField(auto_now_add=True)

2.parent = models.ForeignKey(to=‘self‘,null=True)

UpAndDown表

1.is_up= models.BooleanField()

 

用户表用的是auth认证,

1.from django.contrib.auth.models import AbstractUser

   class UserInfo(AbstractUser):需要继承

2.settings配置

指定自己的auth用户表

AUTH_USER_MODEL = ‘app01.UserInfo‘

 

连接数据库

1.navicat创建数据库

2.

DATABASES = {
‘default‘: {
‘ENGINE‘: ‘django.db.backends.mysql‘,
‘NAME‘: ‘bbs‘,
‘HOST‘:‘127.0.0.1‘,
‘PORT‘:3306,
‘USER‘:‘root‘,
‘PASSWORD‘:‘123‘,

}
}
3.到__init__文件中导入
import pymysql

pymysql.install_as_MySQLdb()




配置静态文件
STATICFILES_DIRS= [
os.path.join(BASE_DIR, ‘static‘)

]
数据迁移,执行两行命令
python3 manage.py makemigrations
python3 manage.py migrate

创建自定义from组件
在app01下创建文件myforms.py
技术分享图片
 1 from django import forms
 2 from django.forms import widgets
 3 from app01 import models
 4 
 5 
 6 class RegForm(forms.Form):
 7     username = forms.CharField(max_length=8,min_length=3,label=用户名,error_messages={
 8                                 max_length:用户名最长8位,
 9                                 min_length:用户名最少3位,
10                                 required:用户名不能为空,
11     },widget=widgets.TextInput(attrs={class:form-control}))
12     password = forms.CharField(max_length=8, min_length=3, label=密码, error_messages={
13         max_length: 密码最长8位,
14         min_length: 密码最少3位,
15         required: 密码不能为空,
16     }, widget=widgets.PasswordInput(attrs={class: form-control}))
17     confirm_password = forms.CharField(max_length=8, min_length=3, label=确认密码, error_messages={
18         max_length: 确认密码最长8位,
19         min_length: 确认密码最少3位,
20         required: 确认密码不能为空,
21     }, widget=widgets.PasswordInput(attrs={class: form-control}))
22     email = forms.EmailField(label=邮箱,error_messages={
23                             invalid:邮箱格式错误,
24                             required:邮箱不能为空
25     },widget=forms.EmailInput(attrs={"class":form-control}))
26 
27     # 局部钩子 校验用户名是否已存在
28     def clean_username(self):
29         username = self.cleaned_data.get(username)
30         user = models.UserInfo.objects.filter(username=username).first()
31         if user:
32             self.add_error(username,用户名已存在)
33         else:
34             return username
35 
36     # 全局钩子 校验密码是否一致
37     def clean(self):
38         password = self.cleaned_data.get(password)
39         confirm_password = self.cleaned_data.get(confirm_password)
40         if not password == confirm_password:
41             self.add_error(confirm_password,两次密码不一致)
42         else:
43             return self.cleaned_data
myforms.py

连接路由

技术分享图片
1 from django.conf.urls import url
2 from django.contrib import admin
3 
4 urlpatterns = [
5     url(r^admin/, admin.site.urls),
6 ]
urls.py

 

包裹在div中,方便调节样式,这个加大间距
<div class="form-group">
{{ form.label }} {{ form }}
<span class="errors"></span>
</div>


‘注册居中’
<h2 class="text-center">注册</h2>

分割线
<hr>

{#input框对象点auto_id能够直接获取input的id值#}
<p><label for="{{ foo.auto_id }}">{{ foo.label }}</label>
{{ foo }}
<span class="errors pull-right" style="color: red"></span>
</p>
技术分享图片

$(‘#id_submit‘).click(function () {
console.log($(‘#myform‘).serializeArray())
})

技术分享图片

$(‘#id_submit‘).click(function () {
var formData = new FormData();
$.each($(‘#myform‘).serializeArray(),function(index,obj){
formData.append(obj.name,obj.value)
})

技术分享图片

技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
 7     <meta name="viewport" content="width=device-width, initial-scale=1">
 8     <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
 9     <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
10 </head>
11 <body>
12 <div class="container-fluid">
13     <div class="row">
14         <div class="col-md-6 col-md-offset-3">
15             <h2 class="text-center">注册</h2>
16             <hr>
17             <form id="myform">
18             {% csrf_token %}
19                 {% for foo in form_obj %}
20                     <div class="form-group">
21                         {#input框对象点auto_id能够直接获取input的id值#}
22                         <p><label for="{{ foo.auto_id }}">{{ foo.label }}</label>
23                             {{ foo }}
24                             <span class="errors pull-right" style="color: red"></span>
25                         </p>
26                     </div>
27                 {% endfor %}
28                 <div class="form-group">
29                     <label for="id_myfile">头像
30                         <img src="/static/img/default.jpg" alt="" width="80" style="margin-left: 20px" id="id_img">
31                     </label>
32                     <input type="file" name="myfile" id="id_myfile" style="display: none;">
33                 </div>
34                 <input type="button" class="btn btn-primary pull-right" id="id_button" value="提交">
35             </form>
36         </div>
37     </div>
38 </div>
39 
40 <script>
41     $(#id_myfile).change(function () {
42         // 获取当前用户上传到的文件对象
43         var myfileObj = $(this)[0].files[0];
44         // 需要用文件阅读器这个内置对象
45         var fileReader = new FileReader();
46         // 将文件对象丢给文件阅读器
47         fileReader.readAsDataURL(myfileObj);
48         // 将文件对象放入img标签的src属性中
49         // 当文件对象全部加载完毕再渲染
50         fileReader.onload = function(){
51              $(#id_img).attr(src,fileReader.result);
52         }
53     });
54     $(#id_button).click(function () {
55         var formData = new FormData();
56         {#console.log($(‘#myform‘).serializeArray());  自动获取form表单中所有input框键值对#}
57         $.each($(#myform).serializeArray(),function (index,obj) {
58             {#console.log(index,obj)  知识添加了普通的键值对,文件对象需要你手动添加#}
59             formData.append(obj.name,obj.value)
60         });
61         {#手动添加文件对象#}
62         formData.append(myfile,$(#id_myfile)[0].files[0]);
63         $.ajax({
64             url:‘‘,
65             type:post,
66             data:formData,
67             // 用formdata传数据的时候需要指定两个参数
68             processData:false,
69             contentType:false,
70             success:function (data) {
71                 if(data.code == 100){
72                     location.href = data.url
73                 }else{
74                     $.each(data.msg,function (index,obj) {
75                         // 手动拼接处forms组件渲染的input的id值     id_字段的特点
76                         var targetId = #id_ + index;
77                         $(targetId).next().html(obj[0]).parent().parent().addClass(has-error)
78                     })
79                 }
80             }
81         })
82     });
83     $(input).focus(function () {
84         $(this).next().html(‘‘).parent().parent().removeClass(has-error)
85     })
86 
87 </script>
88 </body>
89 </html>
register.html
技术分享图片
 1 from django.shortcuts import render
 2 from app01 import myforms
 3 from app01 import models
 4 from django.http import JsonResponse
 5 # Create your views here.
 6 def register(request):
 7     back_dic = {code:100,msg:‘‘}
 8     form_obj = myforms.MyForm()
 9     if request.method == POST:
10         form_obj = myforms.MyForm(request.POST)
11         if form_obj.is_valid():
12             data = form_obj.cleaned_data
13             # 将confirm_password去掉
14             data.pop(confirm_password)
15             # 获取用户上传的文件对象
16             file_obj = request.FILES.get(myfile)
17             # 判断用户是否上传了自己的头像
18             if file_obj:
19                 # 往data添加一组键值
20                 data[avatar] = file_obj
21             models.UserInfo.objects.create_user(**data)
22             back_dic[msg] = 注册成功
23             back_dic[url] = /login/
24         else:
25             back_dic[code] = 101
26             back_dic[msg] = form_obj.errors
27         return JsonResponse(back_dic)
28     return render(request,register.html,locals())
views.py

 

 

bbs 注册功能

标签:创建时间   eth   b-   json   attrs   python   拼接   orm   http   

原文:https://www.cnblogs.com/huangxuanya/p/11054938.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!