python 论坛框架_基于Django框架开发BBS项目

一、表设计

1.用户表

继承AbstractUser

扩展

phone 电话号码

avatar 用户头像

create_time 创建时间

外键字段

一对一个人站点表

2.个人站点表

site_name 站点名称

site_title 站点标题

site_theme 站点样式

3.文章标签表

name 标签名

外键字段

一对多个人站点

4.文章分类表

name 分类名

外键字段

一对多个人站点

5.文章表

title 文章标题

desc 文章简介

content 文章内容

create_time 发布时间

数据库字段设计优化(******)

(虽然下述的三个字段可以从其他表里面跨表查询计算得出,但是频繁跨表效率)

up_num点赞数

down_num点踩数

comment_num 评论数

外键字段

一对多个人站点

多对多文章标签

一对多文章分类

6.点赞点踩表

记录哪个用户给哪篇文章点了赞还是点了踩

user ForeignKey(to="User")

article ForeignKey(to="Article")

is_up BooleanField()

7.文章评论表

记录哪个用户给哪篇文章写了哪些评论内容

user ForeignKey(to="User")

article ForeignKey(to="Article")

content CharField()

comment_time DateField()#自关联

parent ForeignKey(to="Comment",null=True)#ORM专门提供的自关联写法

parent ForeignKey(to="self",null=True)7.评论表

根评论和子评论

to='self'

modles.py

from django.contrib.auth.models importAbstractUserclassUserInfo(AbstractUser):

phone= models.BigIntegerField(verbose_name='手机号',null=True)#头像

avatar = models.FileField(upload_to='avatar/',default='avatar/default.png',verbose_name='用户头像')"""给avatar字段传文件对象 该文件会自动存储到avatar文件下 然后avatar字段只保存文件路径avatar/default.png"""create_time= models.DateField(auto_now_add=True)

blog= models.OneToOneField(to='Blog',null=True)classBlog(models.Model):

site_name= models.CharField(verbose_name='站点名称',max_length=32)

site_title= models.CharField(verbose_name='站点标题',max_length=32)#简单模拟 带你认识样式内部原理的操作

site_theme = models.CharField(verbose_name='站点样式',max_length=64) #存css/js的文件路径

classCategory(models.Model):

name= models.CharField(verbose_name='文章分类',max_length=32)

blog= models.ForeignKey(to='Blog',null=True)classTag(models.Model):

name= models.CharField(verbose_name='文章标签',max_length=32)

blog= models.ForeignKey(to='Blog', null=True)classArticle(models.Model):

title= models.CharField(verbose_name='文章标题',max_length=64)

desc= models.CharField(verbose_name='文章简介',max_length=255)#文章内容有很多 一般情况下都是使用TextField

content = models.TextField(verbose_name='文章内容')

create_time= models.DateField(auto_now_add=True)#数据库字段设计优化

up_num = models.BigIntegerField(verbose_name='点赞数',default=0)

down_num= models.BigIntegerField(verbose_name='点踩数',default=0)

comment_num= models.BigIntegerField(verbose_name='评论数',default=0)#外键字段

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

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

tags= models.ManyToManyField(to='Tag',

through='Article2Tag',

through_fields=('article','tag')

)classArticle2Tag(models.Model):

article= models.ForeignKey(to='Article')

tag= models.ForeignKey(to='Tag')classUpAndDown(models.Model):

user= models.ForeignKey(to='UserInfo')

article= models.ForeignKey(to='Article')

is_up= models.BooleanField() #传布尔值 存0/1

classComment(models.Model):

user= models.ForeignKey(to='UserInfo')

article= models.ForeignKey(to='Article')

content= models.CharField(verbose_name='评论内容',max_length=255)

comment_time= models.DateTimeField(verbose_name='评论时间',auto_now_add=True)#自关联

parent = models.ForeignKey(to='self',null=True) #有些评论就是根评论

二、注册功能

注册功能用到的技术点有以下

forms组件

用户头像前端实时展示

ajax

我们之前写forms代码是直接写到views里面的

为了贯彻面向对象思想,我们会把forms组件代码写到单独的一个py文件里,如果说这个项目从头到位就使用一个form组件,直接写在app下面的任意一个自己写的文件里就行,不过记得不要叫forms,这样在导入Django库里的form时会出现问题,可以叫myforms.py或者其他,只要补交forms就行

如果你项目中用到多个不同的forms组件时,那最好还是自己建一个文件夹,然后把对应的forms组件写上对应的名字,然后放在这个文件夹下面,这样也比较清晰

myforms.py

from django importformsfrom app01 importmodelsclassMyRegForm(forms.Form):

username= forms.CharField(label='用户名', min_length=3, max_length=8,

error_messages={'required': '用户名不能为空','min_length': "用户名最少3位",'max_length': "用户名最大8位"},#还需要让标签有bootstrap样式

widget=forms.widgets.TextInput(attrs={'class': 'form-control'})

)

password= forms.CharField(label='密码', min_length=3, max_length=8,

error_messages={'required': '密码不能为空','min_length': "密码最少3位",'max_length': "密码最大8位"},#还需要让标签有bootstrap样式

widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'})

)

confirm_password= forms.CharField(label='确认密码', min_length=3, max_length=8,

error_messages={'required': '确认密码不能为空','min_length': "确认密码最少3位",'max_length': "确认密码最大8位"},#还需要让标签有bootstrap样式

widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'})

)

email= forms.EmailField(label='邮箱',

error_messages={'required': '邮箱不能为空','invalid': '邮箱格式不正确'},

widget=forms.widgets.EmailInput(attrs={'class': 'form-control'})

)#钩子函数

#局部钩子:校验用户名是否已存在

defclean_username(self):

username= self.cleaned_data.get('username')#去数据库中校验

is_exist = models.UserInfo.objects.filter(username=username)ifis_exist:#提示信息

self.add_error('username', '用户名已存在')returnusername#全局钩子:校验两次是否一致

defclean(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的register视图函数

defregister(request):

form_obj=MyRegForm()if request.method == 'POST':

back_dic= {"code": 1000, 'msg': ''}#校验数据是否合法

form_obj =MyRegForm(request.POST)#判断数据是否合法

ifform_obj.is_valid():#print(form_obj.cleaned_data) # {'username': 'jason', 'password': '123', 'confirm_password': '123', 'email': '123@qq.com'}

clean_data = form_obj.cleaned_data #将校验通过的数据字典赋值给一个变量

#将字典里面的confirm_password键值对删除

clean_data.pop('confirm_password') #{'username': 'jason', 'password': '123', 'email': '123@qq.com'}

#用户头像

file_obj = request.FILES.get('avatar')"""针对用户头像一定要判断是否传值 不能直接添加到字典里面去"""

iffile_obj:

clean_data['avatar'] =file_obj#直接操作数据库保存数据

models.UserInfo.objects.create_user(**clean_data)

back_dic['url'] = '/login/'

else:

back_dic['code'] = 2000back_dic['msg'] =form_obj.errorsreturnJsonResponse(back_dic)return render(request,'register.html',locals())

register.html

Title

注册

{% csrf_token %}

{% for form in form_obj %}

{{ form.label }}{{ form }}

{% endfor %}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值