昨天实现了一个简单的博客显示系统,今天实现一个较为完整的博客系统,当然还未进行完整的界面优化,但是发布还是可以实现的。
一、数据库的构建(M)
首先,我们分析一个博客系统的功能:
(1)一个博客可以有多个标签(多对多)
(2)一个博客可以有多条评论(一对多)
(3)一个博客只可以有一个类别(多对一)
接下来,我们分析关系的属性:
博客:标题,作者,内容,发布时间,分类(外键),标签(多对多)等
标签:标签名
类别:分类名
评论:作者,博客(外键),邮箱,内容,发布时间等。
最终,得到数据库的建立(model.py):
#coding=utf-8
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Category(models.Model):
"""
博客分类
"""
name=models.CharField('名称',max_length=30)
class Meta:
verbose_name="类别"
verbose_name_plural=verbose_name
def __unicode__(self):
return self.name
class Tag(models.Model):
name=models.CharField('名称',max_length=16)
class Meta:
verbose_name="标签"
verbose_name_plural=verbose_name
def __unicode__(self):
return self.name
class Blog(models.Model):
title=models.CharField('标题',max_length=32)
author=models.CharField('作者',max_length=16)
content=models.TextField('内容')
pub=models.DateField('发布时间',auto_now_add=True)
category=models.ForeignKey(Category,verbose_name='分类')#多对一(博客--类别)
tag=models.ManyToManyField(Tag,verbose_name='标签')#(多对多)
class Meta:
verbose_name="博客"
verbose_name_plural=verbose_name
def __unicode__(self):
return self.title
class Comment(models.Model):
blog=models.ForeignKey(Blog,verbose_name='博客')#(博客--评论:一对多)
name=models.CharField('称呼',max_length=16)
email=models.EmailField('邮箱')
content=models.CharField('内容',max_length=240)
pub=models.DateField('发布时间',auto_now_add=True)
class Meta:
verbose_name="评论"
verbose_name_plural="评论"
def __unicode__(self):
return self.content
输入命令:
python manage.py makemigrations
python manage.py migrate
完成数据库的构建,为了方便管理后台:
在admin.py里构建以下代码:
from django.contrib import admin
from .models import *
# Register your models here.
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name',)
class TagAdmin(admin.ModelAdmin):
list_display = ('name',)
class BlogAdmin(admin.ModelAdmin):
list_display = ('title','category','content','pub')
class CommentAdmin(admin.ModelAdmin):
list_display = ('blog','name','content','pub')
admin.site.register(Category,CategoryAdmin)
admin.site.register(Tag,TagAdmin)
admin.site.register(Blog,BlogAdmin)
admin.site.register(Comment,CommentAdmin)
二、定义视图函数(V)
在view.py,我们要实现获取显示的所有博客;并根据博客的id显示博客具体内容和评论。
首先,我们定义了一个特殊的forms.py模块,方便评论的集成。定义如下:
#coding=utf-8
from django import forms
"""
借此完成博客的评论功能
"""
class CommentForm(forms.Form):
name=forms.CharField(label='称呼',max_length=16,error_messages={
'required':'请填写您的称呼',
'max_length':'称呼太长咯'
})
email=forms.EmailField(label='邮箱',error_messages={
'required':'请填写您的邮箱',
'invalid':'邮箱格式不正确'
})
content=forms.CharField(label='内容',error_messages={
'required':'请填写您的评论内容!',
'max_length':'评论内容太长咯'
})
该模块用于view.py模块以及具体博客评论;
View.py:
#coding=utf-8
from django.shortcuts import render,render_to_response
from .models import *
from .forms import CommentForm
from django.http import Http404
def get_blogs(request):
blogs=Blog.objects.all().order_by('-pub')#获得所有的博客按时间排序
return render_to_response('blog_list.html',{'blogs':blogs})#传递context:blog参数到固定页面。
def get_details(request,blog_id):
#检查异常
try:
blog=Blog.objects.get(id=blog_id)#获取固定的blog_id的对象;
except Blog.DoesNotExist:
raise Http404
if request.method == 'GET':
form = CommentForm()
else:#请求方法为Post
form = CommentForm(request.POST)
if form.is_valid():
cleaned_data=form.cleaned_data
cleaned_data['blog']=blog
Comment.objects.create(**cleaned_data)
ctx={
'blog':blog,
'comments': blog.comment_set.all().order_by('-pub'),
'form': form
}#返回3个参数
return render(request,'blog_details.html',ctx)
配置url:
from django.conf.urls import url
from django.contrib import admin
from blog.views import *
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/$',get_blogs),
url(r'^detail/(\d+)/$',get_details,name='blog_get_detail'),
]
三 模板系统(T)
blog_list.html
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>我的博客title>
<style type="text/css">
.blog{
padding: 20px 0px;
}
.blog .info span{
padding-right: 10px;
}
.blog .summary{
padding-top: 20px;
}
style>
head>
<body>
<div class="header">
<h1 align="center">我的博客h1>
div>
{% for blog in blogs %}
<div align="center" class="blog">
<div class="title">
<a href="{% url 'blog_get_detail' blog.id %}"><h2>{{ blog.title }}h2>a>
div>
<div class="info">
<span class="category" style="color: #ff9900;">{{ blog.category.name }}span>
<span class="author" style="color: #4a86e8;">{{ blog.author }}span>
<span class="pub" style="color: #6aa84e">{{ blog.pub }}span>
div>
<div class="summary">
{{ blog.content | truncatechars:100 }}
div>
div>
{% endfor %}
body>
html>
blog_details.html:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ blog.title }}title>
<style type="text/css">
.blog{
padding: 20px 0px;
}
.blog .info span{
padding-right: 10px;
}
.blog .summary{
padding-top: 20px;
}
style>
head>
<body>
<div class="header">
<span><a href="{% url 'blog_get_detail' blog.id %}">{{ blog.title }}a> span>
div>
<div class="content">
<div class="blog">
<div class="title">
<a href="#"><h2>{{ blog.title }}h2>a>
div>
<div class="info">
<span class="category" style="color:#ff9900 ;">{{ blog.category.name }}span>
<span class="author" style="color: #4a86e8">{{ blog.author }}span>
<span class="pub" style="color: #6aa84f">{{ blog.pub }}span>
div>
<div class="summary">
{{ blog.content }}
div>
<div class="comment">
<div class="comment-diaplay" style="padding-top: 20px;">
<h3>评论h3>
{% for comment in comments %}
<div class="comment-field" style="padding-top: 10px;">
{{ comment.name }}说:{{ comment.content }}
div>
{% endfor %}
div>
<div class="comment-post" style="padding-top: 20px ;">
<h3>提交评论h3>
<form action="{% url 'blog_get_detail' blog.id %}" method="post">
{% csrf_token %}
{% for field in form %}
<div class="input-field" style="padding-top: 10px;">
{{ field.label }}:{{ field }}
div>
<div class="error" style="color: red;">
{{ field.errors }}
div>
{% endfor %}
<button type="submit" style="margin-top:10px ">提交button>
<input type="button" value="返回">
form>
div>
div>
div>
div>
body>
html>
运行python manage.py runserver;输入网址:http://127.0.0.1:8000/blog/,得到网页内容:
这里的博客功能已经具有了,但是还不完善,还有一些功能有待日后补充。
补充修改过的博客主页,借鉴了实战一里的内容。
具体代码:
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>我的博客title>
<style type="text/css">
body{
color: #efd;
background: #CCCCCC;
padding: 12px 5em;
margin:7px;
}
h1{
margin-top: -10px;
padding: 2em ;
background: #675;
}
h2{
color: #85F2F2;
border-top: 1px dotted #fff;
margin-top:2em;
}
.blog{
padding: 20px 0px;
}
.blog .info span{
padding-right: 10px;
}
.blog .summary{
padding-top: 20px;
}
style>
head>
<body>
<div class="header">
<h1 align="center">我的博客h1>
div>
<h3 style="margin-bottom: -50px;font-size: x-large;">博客列表
h3>
<hr/>
{% for blog in blogs %}
<div align="center" class="blog">
<div class="title">
<a href="{% url 'blog_get_detail' blog.id %}"><h2 align="left">{{ blog.title }}h2>a>
div>
<div class="info" align="left">
<span class="category" style="color: #ff9900;">{{ blog.category.name }}span>
<span class="author" style="color: #4a86e8;">{{ blog.author }}span>
<span class="pub" style="color: #6aa84e">{{ blog.pub }}span>
div>
<div class="summary">
{{ blog.content | truncatechars:100 }}
div>
div>
{% endfor %}
body>
html>