基於Django的博客系統

目前本項目已經上線,能夠直接在GEEK瀏覽本項目效果:http://blog.huangyongchi.com/
html

全新的項目源碼地址:https://github.com/hyyc554/YcBlogpython

1.項目需求

  • 基於ajax和用戶認證組件實現登陸驗證
  • 基於ajax和form組件實現註冊功能
  • 系統首頁文章列表的渲染
  • 我的站點頁面設計
  • 文章詳細頁的繼承
  • 點贊與踩滅
  • 評論功能
  • 富文本編輯器的使用
  • 防止xss攻擊

2.項目詳情

2.1 數據庫設計

核心代碼:git

1.繼承AbstractUser 2.中介模型 3.聯合惟一

 


           

 

from django.db import models ​ # Create your models here.
​ ​ from django.contrib.auth.models import AbstractUser ​ ​ class UserInfo(AbstractUser): """ 用戶信息 """ nid = models.AutoField(primary_key=True) telephone = models.CharField(max_length=11, null=True, unique=True) avatar = models.FileField(upload_to='avatars/', default="avatars/default.png") create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) ​ blog = models.OneToOneField(to='Blog', to_field='nid', null=True, on_delete=models.CASCADE) ​ def __str__(self): return self.username ​ ​ class Blog(models.Model): """ 博客信息 """ nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='我的博客標題', max_length=64) site_name = models.CharField(verbose_name='站點名稱', max_length=64) theme = models.CharField(verbose_name='博客主題', max_length=32) ​ def __str__(self): return self.title ​ ​ class Category(models.Model): """ 博主我的文章分類表 """ nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='分類標題', max_length=32) blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid', on_delete=models.CASCADE) ​ def __str__(self): return self.title ​ ​ class Tag(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='標籤名稱', max_length=32) blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid', on_delete=models.CASCADE) ​ def __str__(self): return self.title ​ ​ class Article(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=50, verbose_name='文章標題') desc = models.CharField(max_length=255, verbose_name='文章描述') create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) content = models.TextField() ​ comment_count = models.IntegerField(default=0) up_count = models.IntegerField(default=0) down_count = models.IntegerField(default=0) ​ user = models.ForeignKey(verbose_name='做者', to='UserInfo', to_field='nid', on_delete=models.CASCADE) category = models.ForeignKey(to='Category', to_field='nid', null=True, on_delete=models.CASCADE) tags = models.ManyToManyField( to="Tag", through='Article2Tag', through_fields=('article', 'tag'), ) ​ def __str__(self): return self.title ​ ​ class Article2Tag(models.Model): nid = models.AutoField(primary_key=True) article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid', on_delete=models.CASCADE) tag = models.ForeignKey(verbose_name='標籤', to="Tag", to_field='nid', on_delete=models.CASCADE) ​ class Meta: unique_together = [ ('article', 'tag'), ] ​ def __str__(self): v = self.article.title + "---" + self.tag.title return v ​ ​ class ArticleUpDown(models.Model): """ 點贊表 """ ​ nid = models.AutoField(primary_key=True) user = models.ForeignKey('UserInfo', null=True, on_delete=models.CASCADE) article = models.ForeignKey("Article", null=True, on_delete=models.CASCADE) is_up = models.BooleanField(default=True) ​ class Meta: unique_together = [ ('article', 'user'), ] ​ ​ class Comment(models.Model): """ ​ 評論表 ​ """ nid = models.AutoField(primary_key=True) article = models.ForeignKey(verbose_name='評論文章', to='Article', to_field='nid', on_delete=models.CASCADE) user = models.ForeignKey(verbose_name='評論者', to='UserInfo', to_field='nid', on_delete=models.CASCADE) content = models.CharField(verbose_name='評論內容', max_length=255) create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) parent_comment = models.ForeignKey('self', null=True, on_delete=models.CASCADE) ​ def __str__(self): return self.content ​
View Code

 

2.2 站點管理

核心代碼:github

from django.contrib import admin ​ # Register your models here.
from blog import models ​ admin.site.register(models.UserInfo) admin.site.register(models.Article) admin.site.register(models.Article2Tag) admin.site.register(models.ArticleUpDown) admin.site.register(models.Blog) admin.site.register(models.Category) admin.site.register(models.Comment) admin.site.register(models.Tag)
View Code
 

2.3 註冊

核心代碼:面試

1.form組件 1.form組件 class RegForm(forms.Form):pass 局部鉤子 全局鉤子 ​ 2.上傳頭像 avatar 圖像預覽 var reader = new FileReader(); 上傳文件 formdata = new FormData(); ​ 3.用戶文件配置 avatar = models.FileField(upload_to='avatars/', default='avatars/default.png') MEDIA_ROOT = os.path.join(BASE_DIR, 'blog', 'media') MEDIA_URL = '/media/' re_path(r'media/(?P<path>.*)$',serve,{'document_root':settings.MEDIA_ROOT})

 


 

2.4 登陸

核心代碼:ajax

1.驗證碼 隨機生成5個字符,0-9 a-z A-Z ​ pip install pillow from PIL import Image, ImageDraw, ImageFont image = Image.new() ​ 在內存中生成圖片直接返回 from io import BytesIO f = BytesIO() ​ 2.request.session['valid_str'] = valid_str 存在session中,爲了以後登陸,驗證是否經過 ​ 3.驗證碼點擊刷新: $('#valid_img').click(function () { $(this)[0].src += '?' }); ​ 4.認證組件 valid_str = request.session.get('valid_str') if valid_str.upper() == valid_code.upper(): user = auth.authenticate(username = user, password = pwd) if user: auth.login(request, user)

 

 
 

2.5 網站首頁

核心代碼:數據庫

1.bootstrap搭建頁面 ​ 2.導航條 登陸: username / 註銷 未登陸: 登陸 / 註冊 ​ 3.for循環 {% for article in article_list %} {% endfor %}

 


網頁底部分頁器:django

2.6 我的站點

1.文章列表,分類列表,標籤列表,日期歸檔列表 文章列表: /blog/egon/ 分類列表: /blog/egon/cate/python 標籤列表: /blog/egon/tag/生活 日期歸檔列表: /blog/egon/archive/2018-062.模板繼承 {% extends 'base.html' %} ​ {% block content %} {% endblock content%}} ​ 3.自定義標籤 /blog/templatetags/my_tag.py ​ @register.inclusion_tag('menu.html') def get_menu(username): ... return {} # 去渲染 menu.html
4.分組查詢 .annotate() / extra()應用 多表分組 tag_list = Tag.objects.filter(blog=blog).annotate( count = Count('article')).values_list('title', 'count') ​ 單表分組 / DATE_FORMAT() / extra() date_list = Article.objects.filter(user=user).extra( select={"create_ym": "DATE_FORMAT(create_time,'%%Y-%%m')"}).values('create_ym').annotate( c = Count('nid')).values_list('create_ym', 'c') ​ 5. 時間、區域配置 TIME_ZONE = 'Asia/Shanghai' USE_TZ = False

 



2.7 文章詳情

核心代碼:bootstrap

1.模板繼承 article = Article.objects.filter(pk=article_id).first() {% extends 'base.html' %} {% block content %} ... {{ article.articledetail.content|safe }} {% endblock content %}

 



 2.8 後臺管理

核心代碼:session

1.支持文章編輯 2.支持富文本編輯器(支持渲染已有文章) 3.支持刪除文章 4.防止Xss攻擊(基於BS4) # 防止xss攻擊,過濾script標籤
        soup = BeautifulSoup(content, "html.parser") for tag in soup.find_all(): ​ if tag.name == "script": tag.decompose()

 

 

2.9 批量創建測試數據

核心代碼:

1.定製創建測試數據 2.初始化獲得100條用戶信息,以及爲100個客戶分別添加文章、博客的詳細信息

 

 
def supreme(request): """ 這是數據初始化視圖,將會生成99條測試數據,用戶名爲管理員輸入的字符後,加1_99. 密碼爲管理員填入的密碼 :param request: :return: """ tag_title = ['BASIC', 'C', 'C++', 'PASCAL', 'FORTRAN', 'LISP', 'Prolog', 'CLIPS', 'OpenCyc', 'Fazzy', 'Python', 'PHP', 'Ruby', 'Lua'] category_titles = ['非技術區', '軟件測試', '代碼與軟件發佈', '計算機圖形學', '遊戲開發', '程序人生', '求職面試', '讀書區', '轉載區', 'Windows', '翻譯區', '開源研究', 'Flex'] userlist = [] bolglist = [] article_list = [] tag_list = [] cat_list = [] article2tag_list = [] ​ if request.is_ajax(): ​ form = UserForm(request.POST) response = {'user': None, 'msg': None} if form.is_valid(): ​ response['user'] = form.cleaned_data.get('user') # 生成一條用戶記錄
            user = form.cleaned_data.get('user') ​ pwd = form.cleaned_data.get('pwd') email = form.cleaned_data.get('email') avatar_obj = request.FILES.get('avatar') extra = {} if avatar_obj: extra['avatar'] = avatar_obj with transaction.atomic(): for i in range(1, 100): Blog.objects.create(title='blog%s' % i) ​ UserInfo.objects.create_user(username=user + str(i), password=pwd, email=email, **extra) ​ UserInfo.objects.filter(username=user + str(i)).update(blog_id=i) ​ for title in tag_title: tag_list.append(Tag(title=title, blog_id=i)) ​ for cat in category_titles: cat_list.append(Category(title=cat, blog_id=i)) import random for c in range(1, 7): with open('/home/hyc/PycharmProjects/cnblog/static/superme/%s.txt' % c, 'r', encoding='utf-8') as f: content = f.read() ​ soup = BeautifulSoup(content, "html.parser") for tag in soup.find_all(): if tag.name == "script": tag.decompose() desc = soup.text[0:150] + "..." c_id = 13 * (i - 1) + random.randrange(1, 9) ​ article_list.append( Article(desc=desc, title='article%s' % c, content=content, user_id=i, category_id=c_id)) ​ Category.objects.bulk_create(cat_list) Tag.objects.bulk_create(tag_list) Article.objects.bulk_create(article_list) ​ else: response['msg'] = form.errors return JsonResponse(response) ​ my_from = UserForm ​ return render(request, 'supreme.html', {'from': my_from})
View Code


3.源碼連接: 

https://github.com/hyyc554/BBS_blog

相關文章
相關標籤/搜索