django项目:实现一个完整的博客功能(2)
2018-05-10 15:14
441 查看
上次完成用户模块和模板的继承,此次咱们来完成文章模块部分功能
前戏部分
1.添加应用
2.更改settings配置
3.第三部配置文章模块url
高潮来了
1.在models.py里添加需要的模型类
from django.db import models from datetime import datetime from users.models import UserProfile # Create your models here. class Category(models.Model): """文章类型""" name = models.CharField(max_length=10, verbose_name='文章类型') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间') def __str__(self): return self.name class Meta: verbose_name = '类型信息' verbose_name_plural = verbose_name class ArticleInfo(models.Model): """文章信息,与用户一对多关系,与文章类型一对一关系""" title = models.CharField(max_length=20, verbose_name='文章标题') author = models.ForeignKey(UserProfile, verbose_name='文章作者') category = models.ForeignKey(Category, verbose_name='文章类型') desc = models.TextField(verbose_name='文章描述') content = models.TextField(verbose_name='文章正文') is_delete = models.BooleanField(default=False, verbose_name='是否删除') click_num = models.IntegerField(default=0, verbose_name='浏览量') love_num = models.IntegerField(default=0, verbose_name='点赞量') image = models.ImageField(upload_to='article/%y/%m/%d', verbose_name='文章图片', max_length=200) add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间') def __str__(self): return self.title class Meta: verbose_name = '文章信息' verbose_name_plural = verbose_name class TagInfo(models.Model): """有关文章的标签,与文章多对多关系""" name = models.CharField(max_length=10, verbose_name='标签姓名') article = models.ManyToManyField(ArticleInfo, verbose_name='所属文章') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间') def __str__(self): return self.name class Meta: verbose_name = '标签信息' verbose_name_plural = verbose_name class CommentInfo(models.Model): comment_content = models.CharField(max_length=200, verbose_name='文章评论') comment_art = models.ForeignKey(ArticleInfo, verbose_name='所属文章') comment_man = models.ForeignKey(UserProfile, verbose_name='评论人') is_delete = models.BooleanField(default=False, verbose_name='是否删除') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间') def __str__(self): return self.comment_content class Meta: verbose_name = '评论信息' verbose_name_plural = verbose_name2.来创建一个超级后台管理
3. 要上传图片,配置媒体文件夹
总路由url添加:
settings添加:
settings应用进程添加最后一行:
上传完图片后django自动添加媒体目录
4 .在articles的admin.py里添加后台要显示的内容
from django.contrib import admin from .models import ArticleInfo, TagInfo, Category # Register your models here. class ArticleInfoAdmin(admin.ModelAdmin): """文章内容""" list_display = ['title', 'author', 'category', 'desc', 'content', 'is_delete', 'click_num', 'love_num', 'image', 'add_time'] fields = ['title', 'author', 'category', 'desc', 'content', 'is_delete', 'click_num', 'love_num', 'image', 'add_time'] class TagInfoAdmin(admin.ModelAdmin): """标签内容""" list_display = ['name', 'add_time'] fields = ['name', 'article', 'add_time'] filter_horizontal = ['article'] class CategoryAdmin(admin.ModelAdmin): """文章类型内容""" list_display = ['name', 'add_time'] fields = ['name', 'add_time'] admin.site.register(ArticleInfo, ArticleInfoAdmin) admin.site.register(Category, CategoryAdmin) admin.site.register(TagInfo, TagInfoAdmin)5 . 去超帅的django后台看一看
6 . 主页实现最关键部分
from django.shortcuts import render, redirect from .models import UserProfile from django.core.urlresolvers import reverse from articles.models import ArticleInfo, TagInfo from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage # Create your views here. def index(request): """主页程序""" # 首先获取所有文章 all_articles = ArticleInfo.objects.all() # 文章按照日期归档,按天排序参数就是day, 最新发表的要排在最前面 # 所以设置order='DESC' ,默认是时间最小的排在最前面 date_time = all_articles.datetimes('add_time', 'day', order='DESC') # 浏览量排行, 倒序排列加 - ,得到的是一个列表,取前六篇文章 click_sort = all_articles.order_by('-click_name')[:6] # 站长推荐, 时间排序, 最新的用倒序, 同上 pro_arts = all_articles.order_by('-add_time')[:6] # 获得所有标签, 呈现在页面上 all_tags = TagInfo.objects.all() # 获得归档文本的时间, 从html页面传回要查看的参数 year = request.GET.get('year', '') month = request.GET.get('month', '') day = request.GET.get('day', '') if year and month and day: # 按照日期筛选文章 all_articles = all_articles.filter(add_time__year=year, add_time__month=month, add_time__day=day) all_articles_set = set(all_articles) # 从html页面传回tagid的参数,获得点击的标签的id值,通过tagid传参 tagid = request.GET.get('tagid', '') # 此处设置目的是当点击日期和标签时,要呈现的就不是所有文章了, # 取标签和日期的交集, 把列表转化为集合再赋值 if tagid: # 通过tagid获得tag,然后通过tag多对多关系获得所有文章 tag = TagInfo.objects.filter(id=int(tagid))[0] all_articles = tag.article.all() all_articles_set1 = set(all_articles) try: a = list(all_articles_set & all_articles_set1) if a: all_articles = a except: pass # 分页器对象, 设置所有文章每页显示三篇 pa = Paginator(all_articles, 3) # 从html页面传回要查看的哪一页的参数,默认值为1 pagenum = request.GET.get('pagenum', 1) try: pages = pa.page(pagenum) except PageNotAnInteger: # 前一页最尽头就是第一页 pages = pa.page(1) except EmptyPage: # 下一页最尽头就是最后一页, num_pages是总的页数 pages = pa.page(pa.num_pages) # 所有相关参数传回HTML页面 return render(request, 'index.html', { # 'all_articles': all_articles 'pages': pages, # 分页文章 'click_sort': click_sort, # 阅读量排序 'pro_arts': pro_arts, # 推荐排序 'all_tags': all_tags, # 呈现所有标签 'tagid': tagid, 'date_time': date_time, 'year': year, 'month': month, 'day': day })
7. html页面相关代码
分页<ul id="pagination-flickr"> {% if pages.has_previous %} <li class="previous-off"> <a href="{% url 'index' %}?pagenum={{ pages.previous_page_number }}&tagid={{ tagid }}&year={{ year }}&month={{ month }}&day={{ day }}">«上一页</a> </li> {% endif %} <li class="active">{{ pages.number }}/{{ pages.paginator.num_pages }} </li> {% if pages.has_next %} <li class="next"> <a href="{% url 'index' %}?pagenum={{ pages.next_page_number }}&tagid={{ tagid }}&year={{ year }}&month={{ month }}&day={{ day }}">下一页 »</a> </li> {% endif %} </ul>文章归档(请求方式传参)
<h3>文章归档</h3> <ul> {% for date in date_time %} <li> <p><span class="tutime font-size-18"> <a href="{% url 'index' %}?year={{ date.year }}&month={{ date.month }}&day={{ date.day }}">{{ date.year }}年{{ date.month }}月{{ date.day }}日文章归档</a></span> </p> </li> {% endfor %} </ul>标签云(请求方式传参)
<h3>标签云</h3> <ul> {% for tag in all_tags %} <li><a href="{% url 'index' %}?tagid={{ tag.id }}&pagenum={{ pages.number }}">{{ tag.name }}</a> </li> {% endfor %} </ul>文章评论详情
# 加修饰器, 没有登录用户点击后跳转制定路径 @login_required(login_url='/users/user_login/') def comment_add(request, art_id): """文章评论详情""" if request.user: print(request.user) if art_id: content = request.POST.get('comment', '') print(content) com = Comment() com.comment_man_id = request.user.id com.comment_art_id = int(art_id) com.comment_content = content com.save() return redirect(reverse('articles:article_detail', args=[art_id]))点赞(ajax异步)
def love_add(request, art_id): """点赞设置""" if request.is_ajax(): art = ArticleInfo.objects.filter(id=int(art_id))[0] art.love_name += 1 art.save() result = {'a': 'ok'} return JsonResponse(result)
{% block myjs %} <script src="{% static 'js/jquery.min.js' %}"></script> <script> $(function () { $('#dian').click(function () { $.get("{% url 'articles:love_add' article.id %}", function(callback){ if (callback.a == 'ok') { value = parseInt($('#zan').text()); value = value + 1; $('#zan').text(value); setTimeout(function () { window.location.href = '/'; },5000) } }) }) }) </script> {% endblock %}
阅读更多
相关文章推荐
- 自己写的一个项目中实现的购物车功能!购物车页面以及实现购物车相应的dao包!
- 在一个项目中所有的Ajax功能用一个页面来实现
- 超详细asp.net实现一个完整的登录功能
- Rails实现一个blog项目02-登录功能和session的实现
- 一个实现图片上传/产生缩略图/在上传图片上写字功能的完整页面代码
- Android 一个相对完整的自动升级功能实现代码
- 有段时间没有更新博客了,最近比较忙,今天和大家分享一个使用Swift实现的新特性功能吧
- 第8周项目1.3 定义一个完整的类 实现复数加实数 实数加复数
- 第7周-项目1-完整实现复数类中的运算符重载-扩展+、-、*、/运算符的功能
- 项目1-3 定义一个定义完整的类。这样的类在(2)的基础上,扩展+、-、*、/运算符的功能,使之能与double型数据进行运算。设Complex c; d
- 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。
- django+mysql实现一个简单的博客系统
- hchxxzx--》一个实现图片上传/产生缩略图/在上传图片上写字功能的完整页面代码
- Asp.Net MVC3 简单入门第一季(五) 通过Asp.Net MVC的区域功能实现将多个MVC项目部署到一个站点
- 在一个项目中所有的Ajax功能用一个页面来实现
- Django项目部署(阿里云)(1)--基本功能实现
- 以前经常来这里,但是很少写博客.最近在做silverlight 项目.前几天被一个 类似.netmarquee的循环滚动的功能憋了很长时间,现在和大家分享下.
- 一个完整项目的实现
- 通过Asp.Net MVC的区域功能实现将多个MVC项目部署到一个站点
- 【项目1】实现复数类中的运算符重载---(3)一个定义完整的类