项目:开发一个简单的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对比;从数据库返回当前模块
{% 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
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跟当前路径 在登录后才会返回当前页面!