天天看点

python bbs论坛_python 学习笔记二十 django项目bbs论坛

项目:开发一个简单的BBS论坛

需求:

整体参考“抽屉新热榜” + “虎嗅网”

实现不同论坛版块

帖子列表展示

帖子评论数、点赞数展示

在线用户展示

允许登录用户发贴、评论、点赞

允许上传文件

帖子可被置顶

可进行多级评论

就先这些吧。。。

知识必备:

Django

HTML\CSS\JS

BootStrap

Jquery

1.设计表结构

在做项目之前只要涉及到数据库,就一定要把表结构想清楚,表结构没有做出来,就不要动手写代码,这是做开发最起码要坚持的一个原则。

表结构可以帮你理清思路,表结构是体现了你业务逻辑关系的。

fromdjango.db import modelsfromdjango.contrib.auth.models import Userfromdjango.core.exceptions import ValidationError

import datetime

# Create your models here.classArticle(models.Model):

# 文章标题可以重名,不同的用户id就可以分别

title= models.CharField(max_length=255)

# 简介可以为空

brief= models.CharField(null=True,blank=True,max_length=255)

# 所属版块 Category类位于Article下面时,调用需要加上引号

category= models.ForeignKey("Category")

content= models.TextField(u"文章内容")

author= models.ForeignKey("UserProfile")

# auto_now 和 auto_now_add 区别?

# 每次对象修改了,保存都会更新auto_now的最新时间

# 每次对象创建的时候,会生成auto_now_add 时间

pub_date= models.DateTimeField(blank=True, null=True) # 为什么不写auto_now_add?

last_modify= models.DateTimeField(auto_now=True)

# 文章置顶功能

priority= models.IntegerField(u"优先级",default=1000)

head_img= models.ImageField(u"文章标题图片",upload_to="uploads")

status_choices= (('draft',u"草稿"),

('published',u"已发布"),

('hidden',u"隐藏"),

)

status= models.CharField(choices=status_choices,default='published',max_length=32)

def __str__(self):returnself.title

def clean(self): # 自定义model验证(除django提供的外required max_length 。。。),验证model字段的值是否合法

# Don't allow draft entries to have a pub_date.

if self.status == 'draft' and self.pub_date isnot None:

raise ValidationError(('Draft entries may not have a publication date.'))

# Set the pub_datefor published items if it hasn't been set already.

if self.status == 'published' and self.pub_date isNone:

self.pub_date=datetime.date.today()classComment(models.Model):

article= models.ForeignKey(Article,verbose_name=u"所属文章")

# 关联到同一张表的时候需要关联自己用self,当关联自己以后 想反向查找需要通过related_name来查,

# 顶级评论不用包含父评论

parent_comment= models.ForeignKey('self',related_name='my_children',blank=True,null=True)

comment_choices= ((1,u'评论'),

(2,u"点赞"))

comment_type= models.IntegerField(choices=comment_choices,default=1)

user= models.ForeignKey("UserProfile")

comment= models.TextField(blank=True,null=True)# 问题来了? 点赞不用内容,但是评论要内容啊!!!

date= models.DateTimeField(auto_now_add=True)

# django clean方法可以实现表字段验证

#Model.clean()[source]

#This method should be used to provide custom model validation, and to modify attributes on your modelifdesired.

# For instance, you could use it to automatically provide a valuefora field,

# or todovalidation that requires access to more than a single field:

def clean(self):if self.comment_type == 1 and len(self.comment) ==0:

raise ValidationError(u'评论内容不能为空,sb')

def __str__(self):return "C:%s" %(self.comment)classCategory(models.Model):

name= models.CharField(max_length=64,unique=True)

brief= models.CharField(null=True,blank=True,max_length=255)

# 一般页面的版块是固定死的,但是我们想动态生成版块的时候,我们需要定义一个位置字段和是否显示字段

# 一般常规的网站首页都是固定的

set_as_top_menu= models.BooleanField(default=False)

position_index=models.SmallIntegerField()

# 可以有多个管理员

admins= models.ManyToManyField("UserProfile",blank=True)

def __str__(self):returnself.nameclassUserProfile(models.Model):"""在用户表中定义一个friends 字段,关联自己""" user =models.OneToOneField(User)

name=models.CharField(max_length=32)

signature= models.CharField(max_length=255,blank=True,null=True)

head_img= models.ImageField(height_field=150,width_field=150,blank=True,null=True)

#forweb qq

friends= models.ManyToManyField('self',related_name="my_friends",blank=True)

def __str__(self):return self.name

配置Django Admin

fromdjango.contrib import adminfrombbs import models

# Register your models here.classArticleAdmin(admin.ModelAdmin):

list_display= ('title','category','author','pub_date','last_modify','status','priority')classCommentAdmin(admin.ModelAdmin):

list_display= ('article','parent_comment','comment_type','comment','user','date')classCategoryAdmin(admin.ModelAdmin):

list_display= ('name','set_as_top_menu','position_index')

admin.site.register(models.Article,ArticleAdmin)

admin.site.register(models.Comment, CommentAdmin)

admin.site.register(models.UserProfile)

admin.site.register(models.Category,CategoryAdmin)

选择合适的前端模板

....

前端实现动态菜单

首页菜单实现动态展示,首先将版块取出来,排序(在数据库中放两个字段,一个是是否可以展示在前端首页,另一个是它放置的位置),展示不同版块的内容,当前版块高亮显示。有两种实现方式:通过js获取当前url对比;从数据库返回当前模块

python bbs论坛_python 学习笔记二十 django项目bbs论坛
python bbs论坛_python 学习笔记二十 django项目bbs论坛

{% block top-menu %}{% for category in category_list %}

//1.循环后端返回的版块列表 2.后端需要返回当前版块 3.当前版块id同循环版块列表对比 4.给当前版块加上active

{% if category.id == category_obj.id %}{{ category.name }}{% else %}{{ category.name }}{% endif %}

{% endfor %}{% endblock %}

html

python bbs论坛_python 学习笔记二十 django项目bbs论坛
python bbs论坛_python 学习笔记二十 django项目bbs论坛

category_list = models.Category.objects.filter(set_as_top_menu=True,).order_by('position_index')

def index(request):

category_obj= models.Category.objects.get(position_index=1) #首页需要acitve cls,手动定义返回

article_list= models.Article.objects.filter(status='published')return render(request, 'bbs/index.html', {'category_list': category_list,'article_list': article_list,'category_obj': category_obj,

})

def category(request, id):

#获取板块对象

category_obj= models.Category.objects.get(position_index=id)if category_obj.id == 1: #判断首页

article_list= models.Article.objects.filter(status='published') #获取已发布的文章else:#获取当前板块下已发布的文章

article_list= models.Article.objects.filter(category_id=category_obj.id, status='published')return render(request, 'bbs/index.html', {'category_list': category_list,'article_list': article_list,'category_obj': category_obj,

})

Views

文章评论功能

当我们浏览完文章,想评论的时候,提示登录,当登录成功后返回到当前页面,这个要怎么实现呢?

{% if request.user.is_authenticated %} //验证用户是否登录

评论

{% else %}//登录成功 返回的a标签href=当前url后面加上?next跟当前路径 在登录后才会返回当前页面!