python写的博客系统_python实战----博客系统(完善)

上一篇‘博客系统’的博客还没有实现评论,按标签搜索、按日期搜索、按分类搜索的功能,这篇博客主要是对以上功能的增加。

增添评论

第一步:新建app:comment,在主setting.py中添加新app,修改主urls.py文件

from django.conf.urls import url, include

from django.contrib import admin

urlpatterns = [

url(r'^admin/', admin.site.urls),

url(r'',include('blog.urls')),

url(r'',include('comments.urls')),

]

第二步:编写评论的数据库表单

from django.contrib.auth.models import User

from django.db import models

# Create your models here.

from blog.models import Post

class Comment(models.Model):

user =models.ForeignKey(User,verbose_name='用户')

email = models.EmailField(verbose_name='电子邮箱')

text = models.TextField(max_length=255,verbose_name='评论正文')

# auto_now_add=True 自动create_time为最新一次更改评论信息的时间

create_time = models.DateTimeField(auto_now_add=True,verbose_name='创建时间')

post = models.ForeignKey(Post)

class Meta:

verbose_name = '评论'

verbose_name_plural = '评论'

def __str__(self):

return self.text[:4]

第三步:编写评论的路由comment.urls.py和comment.views.py

# comment.views.py

from django.shortcuts import render, get_object_or_404,redirect

# Create your views here.

from blog.models import Post

from comments.forms import CommentForm

def post_comment(request, id):

# 1. 获取用户选择的博客

post = get_object_or_404(Post, id=id)

# 2. 如果用户提交评论

if request.method == 'POST':

print(request.POST)

form = CommentForm(request.POST)

# 2.1 判断表单是否合法

if form.is_valid():

comment = form.save(commit=False)

comment.post = post

comment.save()

# 2.2 如果不合法,则提交错误信息

else:

return render(request, 'blog/detail.html',

context={

'errors': form.errors

})

# 3. 如果不是POST请求,访问用户详情页

return redirect(post.get_url())

# comment.urls

from django.conf.urls import url, include

from django.contrib import admin

from comments import views

app_name = 'comment'

urlpatterns = [

url(r'^comment/blog/(?P\d+)/$',views.post_comment,name='post_comment'),

]

第四步:编写评论表单

# 同步与数据库评论的形式

from comments.models import Comment

class CommentForm(forms.ModelForm):

class Meta:

model = Comment

fields = ['user','email','text']

第五步:修改HTML文件中关于评论的部分


发表评论

{% csrf_token %}

{{ form.user.label }}

{{ form.user }}

{{ form.email.label }}

{{ form.email }}

{{ form.text.label }}

{{ form.text }}

发表

评论列表,共 {{ comments.count }} 条评论

{% for comment in comments %}

{{ comment.user }}

datetime="{{ comment.create_time }}">{{ comment.create_time }}

{{ comment.text }}

{% endfor %}

自定义标签

实现按标签搜索、按日期搜索、按分类搜索的功能

第一步:自定义标签

准备(必需)工作:

在某个app下创建一个名为templatetags(必需,且包名不可变)的包。假设我们在名为blog的app下创建了一个templatetags的包,并在该包下创建了一个名为blog_tags的文件.

确保settings文件中的INSTALLD_APPS内必须含有该app

修改setting.py有关时间显示的部分

# TIME_ZONE = 'UTC'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

#如果setting中配置USE_TZ=True则输出的是UTC时间(naive time),

# 如果setting中配置USE_TZ=False,则该输出时间与datetime.datetime.now()完全相同

# USE_TZ = True

USE_TZ = False

2. 接下来在blog_tags文件中写入如下几行

from django import template

register = template.Library()

3. 在模板中使用{% load %} 标签装载自定义标签或者装饰器

from django import template

from django.db.models import Count

from blog.models import Post, Category, Tag

register = template.Library()

@register.simple_tag

def get_recent_posts(num=3):

return Post.objects.all().order_by('-create_time')[:num]

@register.simple_tag

def archives():

return Post.objects.dates(field_name='create_time',

kind='month',

order='DESC')

@register.simple_tag

def get_category():

return Category.objects.annotate(num_posts=Count('post')).filter(num_posts__gt=0)

@register.simple_tag

def get_tags():

# return Tag.objects.all()

return Tag.objects.annotate(num_posts = Count('post'))

第二步: 编写标签查找的路由和视图函数

路由

#blog.urls.py

from django.conf.urls import url

from django.contrib import admin

from blog import views

app_name = 'blog'

urlpatterns = [

url(r'^$', views.index, name='index'),

url(r'blog/(?P\d+)/$', views.detail, name='detail'),

url(r'^archive/(?P\d{4})/(?P\d{1,2})/', views.archive, name='archive'),

url(r'^category/(?P\d+)/', views.category, name='category'),

url(r'^tag/(?P\d+)/', views.tag, name='tag'),

url(r'^search', views.search, name='search')

]

视图函数

from django.db.models import Q

from django.http import HttpResponse

from django.shortcuts import render, get_object_or_404

# Create your views here.

from markdown import markdown

from blog.models import Post, Tag

from comments.forms import CommentForm

def index(request):

# return HttpResponse('ok index!')

posts = Post.objects.all()

return render(request,'blog/index.html',context={

'posts':posts

})

def detail(request,id):

# return HttpResponse('ok,%s detail' %(id))

post = Post.objects.get(id=id)

post.add_views()

form = CommentForm()

comments = post.comment_set.all()

post.body = markdown(post.body,

extensions=['markdown.extensions.extra',

'markdown.extensions.codehilite',

'markdown.extensions.toc', ],

output_format='html')

return render(request,'blog/detail.html',context={

'post':post,

'comments':comments,

'form':form,

})

def archive(request,year,month):

posts = Post.objects.filter(

create_time__year=year,

create_time__month=month

).order_by('-create_time')

return render(request,'blog/index.html',context={

'posts':posts

})

def category(request,id):

posts = Post.objects.filter(category_id=id)

return render(request,'blog/index.html',

context={

'posts':posts

})

def tag(request,id):

tag = get_object_or_404(Tag,id=id)

posts = Post.objects.filter(tags=tag).order_by('-create_time')

return render(

request, 'blog/index.html',

context={

'posts': posts

}

)

def search(request):

query = request.GET.get('query',None)

posts = Post.objects.filter(

Q(title__icontains=query) |

Q(body__icontains=query)

)

if not posts:

return render(request,'blog/index.html',

context={

'posts':posts,

'message':'没有找到相关信息'

}

)

else:

return render(request, 'blog/index.html',

context={

'posts': posts

}

)

第三步:修改Html文件,仅截取部分代码

这里在博客详情页需要显示的是博客的结构(目录),添加显示目录的代码

修改视图函数

def detail(request,id):

# return HttpResponse('ok,%s detail' %(id))

post = Post.objects.get(id=id)

post.add_views()

form = CommentForm()

comments = post.comment_set.all()

# post.body = markdown(post.body,

# extensions=['markdown.extensions.extra',

# 'markdown.extensions.codehilite',

# 'markdown.extensions.toc', ],

# output_format='html')

md = Markdown(

extensions=['markdown.extensions.extra',

'markdown.extensions.codehilite',

'markdown.extensions.toc', ],

output_format='html'

)

# Convert markdown to serialized XHTML or HTML.

post.body = md.convert(post.body)

post.toc = md.toc

return render(request,'blog/detail.html',context={

'post':post,

'comments':comments,

'form':form,

})

右侧导航栏

{# 基模板 #}

{% block toc %}

{% endblock %}

最新文章

{% get_recent_posts as recent_posts %}

{% for post in recent_posts %}

{{ post.title }}

{% endfor %}

归档

{% archives as dates %}

{% for date in dates %}

{{ date.year }}年 {{ date.month }}月

{% endfor %}

分类

{% get_category as categories %}

{% for category in categories %}

{{ category.name }}

class="post-count">({{ category.num_posts }})

{% endfor %}

标签云

{% get_tags as tags %}

{% for tag in tags %}

{{ tag.name }}

{% endfor %}

详情页添加博客目录

{# blog/detail.html #}

{% block toc %}

文章目录

{{ post.toc | safe }}

{% endblock %}

按类别查找

按标签查找

按时间查找

显示博客目录

分页

Django提供了一个新的类来帮助你管理分页数据,这个类存放在django/core/paginator.py.它可以接收列表、元组或其它可迭代的对象。

def index(request):

all_posts = Post.objects.count()

if all_posts % PER_PAGE != 0:

page_nums = all_posts // PER_PAGE + 1

else:

page_nums = all_posts // PER_PAGE

paginator = Paginator(Post.objects.all(),PER_PAGE)

if request.GET.get('page'):

page = request.GET.get('page')

else:

page = 1

try:

posts = paginator.page(page)

except (PageNotAnInteger,EmptyPage):

posts = paginator.page(1)

posts.has_previous()

posts.has_next()

posts.previous_page_number()

posts.next_page_number()

return render(request, 'blog/index.html',

context={

'title':'博客首页',

'posts':posts,

'pages_num':page_nums,

})

修改主页的html文件有关分页显示的部分

{% if posts.has_previous %}

上一页

{% else %}

上一页

{% endif %}

第 {{ posts.number }} 页 / 共 {{ pages_num }} 页

{% if posts.has_next %}

下一页

{% else %}

下一页

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值