Django(博客)

一舌胶、項目概述

項目運行環(huán)境

Python3.6+
Django 1.11
MySQL 5.7
其他插件(圖片處理婴梧、分頁炮沐、驗證碼....)
項目詳細(xì)功能介紹

前臺功能

項目首頁展示

輪播圖

博客推薦

最新發(fā)布

博客分類

最新評論文章

widgets小插件

搜索功能

博客分類功能

博客標(biāo)簽查詢

友情鏈接

博客分頁功能

博客詳細(xì)

最新評論文章

發(fā)表評論

評論展示

評論數(shù)

閱讀數(shù)

登錄功能

注冊功能

郵箱驗證功能

注銷功能

頁面模板

標(biāo)簽云功能

讀者墻功能

后臺功能

用戶維護(hù)

權(quán)限管理

博客分類維護(hù)

標(biāo)簽維護(hù)

友情鏈接

輪播圖維護(hù)

項目演示

項目演示
# 二伊诵、開發(fā)環(huán)境搭建

> 使用virtualenv 和 virtualenwrapper

**1\. MySQL 5.7**

sudo apt install mysql-server mysql-client


**2\. 安裝mysql驅(qū)動**

pip install pymysql


**3\. 安裝Django**

pip install django==1.11


# 三滥嘴、創(chuàng)建項目

## 創(chuàng)建項目和應(yīng)用

*   創(chuàng)建項目

django-admin startproject django-blog


*   創(chuàng)建應(yīng)用

python manage.py startapp userapp

python manage.py startapp blogapp


## 配置數(shù)據(jù)庫

*   在settings中配置數(shù)據(jù)庫

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.mysql',

'NAME': 'django_blog_db',

'USER': 'root',

'PASSWORD': 'wwy123',

'HOST': '127.0.0.1',

'PORT': '3306',

}

}


## 創(chuàng)建數(shù)據(jù)庫(執(zhí)行遷移文件)

python manage.py migrate


## 創(chuàng)建超級管理員

python manage.py createsuperuser


# 四、創(chuàng)建數(shù)據(jù)模型

## USERAPP

### USER(用戶模型)

from django.contrib.auth.models import AbstractUser


class BlogUser(AbstractUser):`


nikename = models.CharField('昵稱', max_length=20, default='')

> 提示:需要在settings配置文件中設(shè)置:AUTH_USER_MODEL = 'users.BlogUser'

### EMAIL(郵箱驗證數(shù)據(jù)模型)

class EmailVerifyRecord(models.Model):`

code = models.CharField(verbose_name='驗證碼', max_length=50,default='')

email = models.EmailField(max_length=50, verbose_name="郵箱")

send_type = models.CharField(verbose_name="驗證碼類型", choices=(("register",u"注冊"),("forget","找回密碼"), ("update_email","修改郵箱")), max_length=30)

send_time = models.DateTimeField(verbose_name="發(fā)送時間", default=datetime.now)

class Meta:

verbose_name = "郵箱驗證碼"


# 復(fù)數(shù)

verbose_name_plural = verbose_name

def str(self):

return '{0}({1})'.format(self.code, self.email)


## BLOGAPP

### Banner(輪播圖模型)

class Banner(models.Model):`

title = models.CharField('標(biāo)題', max_length=50)

cover = models.ImageField('輪播圖', upload_to='static/images/banner')

link_url = models.URLField('圖片鏈接', max_length=100)

idx = models.IntegerField('索引')

is_active = models.BooleanField('是否是active', default=False)

def str(self):

return self.title

class Meta:

verbose_name = '輪播圖'

verbose_name_plural = '輪播圖'


### Category(博客分類模型)

class BlogCategory(models.Model):`

name = models.CharField('分類名稱', max_length=20, default='')

class Meta:

verbose_name = '博客分類'

verbose_name_plural = '博客分類'

def str(self):

return self.name


### Tags(標(biāo)簽?zāi)P?

class Tags(models.Model):`

name = models.CharField('標(biāo)簽名稱', max_length=20, default='')

class Meta:

verbose_name = '標(biāo)簽'

verbose_name_plural = '標(biāo)簽'

def str(self):

return self.name


### Blog(博客模型)

class Post(models.Model):`

user = models.ForeignKey(BlogUser, verbose_name='作者')

category = models.ForeignKey(BlogCategory, verbose_name='博客分類', default=None)

tags = models.ManyToManyField(Tags, verbose_name='標(biāo)簽')

title = models.CharField('標(biāo)題', max_length=50)

content = models.TextField('內(nèi)容')

pub_date = models.DateTimeField('發(fā)布日期', default=datetime.now)

cover = models.ImageField('博客封面', upload_to='static/images/post', default=None)

views = models.IntegerField('瀏覽數(shù)', default=0)

recommend = models.BooleanField('推薦博客', default=False)

def str(self):

return self.title

class Meta:

verbose_name = '博客'

verbose_name_plural = '博客'


### Comment(評論模型)

class Comment(models.Model):`

post = models.ForeignKey(Post, verbose_name='博客')

user = models.ForeignKey(BlogUser, verbose_name='作者')

pub_date = models.DateTimeField('發(fā)布時間')

content = models.TextField('內(nèi)容')

def str(self):

return self.content

class Meta:

verbose_name = '評論'

verbose_name_plural = '評論'


### FriendlyLink(友情鏈接模型)

class FriendlyLink(models.Model):`

title = models.CharField('標(biāo)題', max_length=50)

link = models.URLField('鏈接', max_length=50, default='')

def str(self):

return self.title

class Meta:

verbose_name = '友情鏈接'

verbose_name_plural = '友情鏈接'


# 五换团、實現(xiàn)首頁頁面模板

## 創(chuàng)建模板文件夾

> 創(chuàng)建模板文件templates,并在settings.py中設(shè)置

TEMPLATES = [

{

'BACKEND': 'django.template.backends.django.DjangoTemplates',

'DIRS': [os.path.join(BASE_DIR, 'templates')],

'APP_DIRS': True,

'OPTIONS': {

'context_processors': [

'django.template.context_processors.debug',

'django.template.context_processors.request',

'django.contrib.auth.context_processors.auth',

'django.contrib.messages.context_processors.messages',

],

},

},

]


## 配置靜態(tài)文件路徑

STATIC_URL = '/static/'

STATICFILES_DIRS = (

os.path.join(BASE_DIR, "static"),

)


# 六把还、創(chuàng)建首頁路由

*   創(chuàng)建視圖函數(shù)

def index(request):`

return render(request, 'index.html', {})


*   配置url

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


*   修改模板CSS JS等靜態(tài)文件的路徑

# 七、實現(xiàn)幻燈片功能(Banner)

*   注冊模型

from blogs.models import Banner

admin.site.register(Banner)


*   編寫views

from .models import Banner

def index(request):

banner_list = Banner.objects.all()

ctx = {

'banner_list': banner_list,

}

return render(request, 'index.html', ctx)


*   模板

<div id="focusslide" class="carousel slide" data-ride="carousel">

<ol class="carousel-indicators">

{% for banner in banner_list %}

{% if banner.is_active %}

<li data-target="#focusslide" data-slide-to="{{banner.idx}}" class="active"></li>

{% else %}

<li data-target="#focusslide" data-slide-to="{{banner.idx}}"></li>

{% endif %}

{% endfor %}

</ol>

<div class="carousel-inner" role="listbox">

{% for banner in banner_list %}

{% if banner.is_active %}

<div class="item active">

<a href="{{banner.link_url}}" target="_blank" title="{{banner.title}}" >

<img src="{{banner.cover}}" alt="{{banner.title}}" class="img-responsive"></a>

</div>

{% else %}

<div class="item">

<a href="{{banner.link_url}}" target="_blank" title="{{banner.title}}" >

<img src="{{banner.cover}}" alt="{{banner.title}}" class="img-responsive"></a>

</div>

{% endif %}

{% endfor %}

</div>

<a class="left carousel-control" href="#focusslide" role="button" data-slide="prev" rel="nofollow">

<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>

<span class="sr-only">上一個</span> </a>

<a class="right carousel-control" href="#focusslide" role="button" data-slide="next" rel="nofollow">

<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>

<span class="sr-only">下一個</span> </a>

</div>

``


# 八俏脊、實現(xiàn)博客推薦

*   注冊模型

from blogs.models import Banner,Post,BlogCategory,Tags

...

admin.site.register(BlogCategory)

admin.site.register(Tags)

admin.site.register(Post)


*   編寫views

`# 視圖函數(shù) HTTPRequest`

def index(request):

banner_list = Banner.objects.all()

recommend_list = Post.objects.filter(recommend=1)

ctx = {

'banner_list': banner_list,

'recommend_list': recommend_list,

}

return render(request, 'index.html', ctx)


*   模板

{% for post in recommend_list %}

<article class="excerpt-minic excerpt-minic-index">

    <h2><span class="red">【推薦】</span><a target="_blank" href="/blog/{{post.id}}/" title="{{post.title}}" >{{post.title}}</a>

    </h2>

    <p class="note">{{post.content}}</p>

</article>

{% endfor %}


# 九全谤、實現(xiàn)最新發(fā)布

*   編寫views

`# 視圖函數(shù) HTTPRequest`

def index(request):

...

post_list = Post.objects.order_by('-pub_date').all()[:10]

....

ctx = {

'banner_list': banner_list,

'recommend_list': recommend_list,

'post_list': post_list,

}

return render(request, 'index.html', ctx)


*   模板

{% for post in post_list%}

<article class="excerpt excerpt-1" style="">

<a class="focus" href="/blog/{{post.id}}/" title="{{post.title}}" target="_blank" ><img class="thumb" data-original="/{{post.cover}}" src="/{{post.cover}}" alt="{{post.title}}" style="display: inline;"></a>

    <header><a class="cat" href="#" title="{{post.category.name}}" >{{post.category.name}}<i></i></a>

        <h2><a href="/blog/{{post.id}}/" title="{{post.title}}" target="_blank" >{{post.title}}</a>

        </h2>

    </header>

    <p class="meta">

        <time class="time"><i class="glyphicon glyphicon-time"></i>{{post.pub_date|date:'Y-m-d'}}</time>

        <span class="views"><i class="glyphicon glyphicon-eye-open"></i>{{post.views}}</span> <a class="comment" href="##comment" title="評論" target="_blank" ><i class="glyphicon glyphicon-comment"></i>{{post.comment_set.count}}</a>

</p>

<p class="note">

{% autoescape off %}

{{post.content | truncatechars_html:200}}

{% endautoescape %}

</p>

</article>

{% endfor %}


# 十、實現(xiàn)博客分類功能

*   編寫視圖

`# 視圖函數(shù) HTTPRequest`

def index(request):

banner_list = Banner.objects.all()

recommend_list = Post.objects.filter(recommend=1)

post_list = Post.objects.order_by('-pub_date').all()[:10]

blogcategory_list = BlogCategory.objects.all()

ctx = {

'banner_list': banner_list,

'recommend_list': recommend_list,

'post_list': post_list,

'blogcategory_list': blogcategory_list,

}

return render(request, 'index.html', ctx)


*   模型

<div class="title">

<h3>最新發(fā)布</h3>

<div class="more">

{%for c in blogcategory_list%}

         <a href="/category/{{c.id}}" title="{{c.name}}" >{{c.name}}</a>

        {% endfor %}

    </div>

</div>


# 十一爷贫、實現(xiàn)最新評論功能

*   編寫views

<ul>

{% for post in new_comment_list %}

<li><a title="{{ post.title }}" href="#"><span class="thumbnail">

<img class="thumb" data-original="/{{ post.cover }}"

src="/{{ post.cover }}"

alt="{{ post.title }}" style="display: block;">

        </span><span class="text">{{ post.title }}</span><span class="muted"><i

class="glyphicon glyphicon-time"></i>

{{ post.pub_date }}

        </span><span class="muted"><i class="glyphicon glyphicon-eye-open"></i>{{ post.views }}</span></a></li>

{% endfor %}

</ul>


# 十二认然、實現(xiàn)搜索功能

*   編寫views

from django.views.generic.base import View

from django.db.models import Q

class SearchView(View):

def get(self, request):

pass

def post(self, request):

kw = request.POST.get('keyword')

post_list = Post.objects.filter(Q(title__icontains=kw)|Q(content__icontains=kw))

ctx = {

'post_list': post_list

}

return render(request, 'list.html', ctx)

  • urls

url(r'^search$', SearchView.as_view(), name='search'),


# 十三、實現(xiàn)友情鏈接

*   編寫視圖 (數(shù)據(jù)源)

def index(request):

....

friendlylink_list = FriendlyLink.objects.all()

.....


*   模板

<div class="widget widget_sentence">

<h3>友情鏈接</h3>

<div class="widget-sentence-link">

{% for friendlylink in friendlylink_list %}

<a href="{{ friendlylink.link }}" title="{{ friendlylink.title }}"

target="_blank">{{ friendlylink.title }}</a>&nbsp;&nbsp;&nbsp;

{% endfor %}

</div>

</div>


# 十四漫萄、實現(xiàn)博客列表功能

*   編寫views

def blog_list(request):

post_list = POST.objects.all()

ctx = {

'post_list': post_list,

}

return render(request, 'list.html', ctx)


*   編寫路由

url(r'^list$', blog_list, name='blog_list'),

  • base.html

<!doctype html>

<html lang="zh-CN">

<head>

<meta charset="utf-8">

<meta name="renderer" content="webkit">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{% block title %}知奇博客首頁 {% endblock %}</title>

<meta name="keywords" content="">

<meta name="description" content="">

{% block custom_css %}{% endblock %}

<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css">

<link rel="stylesheet" type="text/css" href="/static/css/nprogress.css">

<link rel="stylesheet" type="text/css" href="/static/css/style.css">

<link rel="stylesheet" type="text/css" href="/static/css/font-awesome.min.css">

<link rel="apple-touch-icon-precomposed" href="/static/images/icon.png">

<link rel="shortcut icon" href="/static/images/favicon.ico">

<script src="/static/js/jquery-2.1.4.min.js"></script>

<script src="/static/js/nprogress.js"></script>

<script src="/static/js/jquery.lazyload.min.js"></script>

</head>

<body class="user-select">

<header class="header">

<nav class="navbar navbar-default" id="navbar">

<div class="container">

<div class="header-topbar hidden-xs link-border">

<ul class="site-nav topmenu">

 <li><a href="#" >標(biāo)簽云</a></li>

    <li><a href="#" rel="nofollow" >讀者墻</a></li>

    <li><a href="#" title="RSS訂閱" >

        <i class="fa fa-rss">

        </i> RSS訂閱

    </a></li>

</ul>

         愛學(xué)習(xí) 更愛分享

</div>

<div class="navbar-header">

<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#header-navbar" aria-expanded="false"> <span class="sr-only"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>

<h1 class="logo hvr-bounce-in"><a href="#" title="知奇課堂博客"><img src="/static/images/201610171329086541.png" alt="知奇課堂博客"></a></h1>

</div>

<div class="collapse navbar-collapse" id="header-navbar">

<ul class="nav navbar-nav navbar-left">

 <li><a data-cont="知奇課堂博客" title="知奇課堂博客" href="/">首頁</a></li>

 <li><a data-cont="博客" title="博客" href="/list">博客</a></li>

</ul>

<ul class="nav navbar-nav navbar-right">

{% if user.is_authenticated %}

<li><a data-cont="用戶" title="用戶" href="#">歡迎卷员,{{user.username}}</a></li>

<li><a data-cont="注冊" title="注冊" href="/logout">注銷</a></li>

{% else %}

<li><a data-cont="登錄" title="登錄" href="/login">登錄</a></li>

<li><a data-cont="注冊" title="注冊" href="/register">注冊</a></li>

{% endif %}

</ul>

</div>

</div>

</nav>

</header>

{% block content %}

{% endblock %}

<footer class="footer">

<div class="container">

<p>Copyright ? 2016.Company name All rights reserved.</p>

</div>

<div id="gotop"><a class="gotop"></a></div>

</footer>

<script src="/static/js/bootstrap.min.js"></script>

``

<script src="/static/js/scripts.js"></script>

</body>

</html>


# 十五、實現(xiàn)分頁功能

*   安裝包

pip install django-pure-pagination


> 參考鏈接: [https://github.com/jamespacileo/django-pure-pagination](https://github.com/jamespacileo/django-pure-pagination)

def blog_list(request):

post_list = Post.objects.all()

try:

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

except PageNotAnInteger:

page = 1

p = Paginator(post_list, per_page=1, request=request)

post_list = p.page(page)

ctx = {

'post_list': post_list,

}

return render(request, 'list.html', ctx)


*   模板

<section class="container">

<div class="content-wrap">

<div class="content">

<div class="title">

<h3 style="line-height: 1.3">博客列表</h3>

</div>

{% for post in post_list.object_list %}

<article class="excerpt excerpt-1"><a class="focus" href="/blog/{{post.id}}" title="{{post.title}}" target="_blank" >

<img class="thumb" data-original="/{{post.cover}}" src="/{{post.cover}}" alt="{{post.title}}" style="display: inline;"></a>

<header><a class="cat" href="/category/{{post.category.id}}" title="{{post.category.name}}" >{{post.category.name}}<i></i></a>

 <h2><a href="/blog/{{post.id}}" title="{{post.title}}" target="_blank" >{{post.title}}</a></h2>

</header>

<p class="meta">

 <time class="time"><i class="glyphicon glyphicon-time"></i> {{post.pub_date|date:'Y-m-d'}}</time>

 <span class="views"><i class="glyphicon glyphicon-eye-open"></i> {{post.views}}</span>

<a class="comment" href="##comment" title="評論" target="_blank" ><i class="glyphicon glyphicon-comment"></i>{{post.comment_set.count}}</a></p>

<p class="note">{{post.content}}</p>

</article>

{% endfor %}

{% include "_pagination.html" %}

  • _pagination.html

{% load i18n %}

<div class="pagination">

{% if post_list.has_previous %}

<a href="?{{ post_list.previous_page_number.querystring }}" class="prev">&lsaquo;&lsaquo; 上一頁</a>

{% else %}

<span class="disabled prev">&lsaquo;&lsaquo; 上一頁</span>

{% endif %}

{% for page in post_list.pages %}

{% if page %}

{% ifequal page post_list.number %}

<span class="current page">{{ page }}</span>

{% else %}

<a href="?{{ page.querystring }}" class="page">{{ page }}</a>

{% endifequal %}

{% else %}

...

{% endif %}

{% endfor %}

{% if post_list.has_next %}

<a href="?{{ post_list.next_page_number.querystring }}" class="next">下一頁 &rsaquo;&rsaquo;</a>

{% else %}

<span class="disabled next">下一頁 &rsaquo;&rsaquo;</span>

{% endif %}

</div>


# 十六腾务、實現(xiàn)標(biāo)簽云功能

class TagMessage(object):

def init(self, tid, name, count):

self.tid = tid

self.name = name

self.count = count

def blog_list(request):

post_list = Post.objects.all()

try:

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

except PageNotAnInteger:

page = 1

p = Paginator(post_list, per_page=1, request=request)

post_list = p.page(page)

tags = Tags.objects.all()

tag_message_list = []

for t in tags:

count = len(t.post_set.all())

tm = TagMessage(t.id, t.name, count)

tag_message_list.append(tm)

ctx = {

'post_list': post_list,

'tags': tag_message_list

}

return render(request, 'list.html', ctx)


*   模板

<h3>標(biāo)簽云</h3>

<div class="widget-sentence-content">

    <ul class="plinks ptags">

{% for t in tags %}

        <li><a href="/tags/{{t.tid}}" title="{{t.name}}" draggable="false">{{t.name}} <span class="badge">{{t.count}}</span></a></li>

{% endfor %}

    </ul>

</div>

</div>


# 十七毕骡、實現(xiàn)分類查詢功能

*   編寫視圖

def blog_list(request, cid=-1):

post_list = None

if cid != -1:

cat = BlogCategory.objects.get(id=cid)

post_list = cat.post_set.all()

else:

post_list = Post.objects.all()

....

ctx = {

'post_list': post_list,

'tags': tag_message_list

}

return render(request, 'list.html', ctx)


*   編寫路由

url(r'^category/(?P<cid>[0-9]+)/$', blog_list),


*   模板 index

<div class="title">

<h3>最新發(fā)布</h3>

<div class="more">

{%for c in blogcategory_list%}

         <a href="/category/{{c.id}}" title="{{c.name}}" >{{c.name}}</a>

        {% endfor %}

    </div>

</div>


# 十八、實現(xiàn)按標(biāo)簽查詢功能

*   編寫views

def blog_list(request, cid=-1, tid=-1):

post_list = None

if cid != -1:

cat = BlogCategory.objects.get(id=cid)

post_list = cat.post_set.all()

elif tid != -1:

tag = Tags.objects.get(id=tid)

post_list = tag.post_set.all()

else:

post_list = Post.objects.all()

....

ctx = {

'post_list': post_list,

'tags': tag_message_list

}

return render(request, 'list.html', ctx)


*   路由設(shè)置

url(r'^tags/(?P<tid>[0-9]+)/$', blog_list),


*   模板

<h3>標(biāo)簽云</h3>

<div class="widget-sentence-content">

<ul class="plinks ptags">

{% for t in tags %}

<li><a href="/tags/{{t.tid}}" title="{{t.name}}" draggable="false">{{t.name}} <span class="badge">{{t.count}}</span></a></li>

{% endfor %}

</ul>

</div>

</div>

</div>


# 十九、實現(xiàn)博客詳情功能

*   定義視圖函數(shù)

def blog_detail(request,bid):

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

post.views = post.views + 1

post.save()


# 博客標(biāo)簽

tag_list = post.tags.all()

ctx = {

'post': post,

}

return render(request, 'show.html', ctx)


*   路由設(shè)置

url(r'^blog/(?P<bid>[0-9]+)/$', blog_detail, name='blog_detail'),


*   前端展示

{% extends 'base.html' %}

{% block title %}知奇博客-詳細(xì) {% endblock %}

{% block content %}

<section class="container">

<div class="content-wrap">

<div class="content">

<header class="article-header">

<h1 class="article-title"><a href="#" title="{{post.title}}" >{{post.title}}</a></h1>

<div class="article-meta"> <span class="item article-meta-time">

 <time class="time" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="發(fā)表時間:{{post.pub_date|date:'Y-m-d'}}">

<i class="glyphicon glyphicon-time"></i> {{post.pub_date|date:'Y-m-d'}}</time>

 </span>

<span class="item article-meta-source" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="來源:{{post.user.username}}">

<i class="glyphicon glyphicon-globe"></i> {{post.user.username}}</span>

<span class="item article-meta-category" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="{{post.category.name}}">

<i class="glyphicon glyphicon-list"></i> <a href="#" title="{{post.category.name}}" >{{post.category.name}}</a></span>

<span class="item article-meta-views" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="瀏覽量:{{post.views}}">

<i class="glyphicon glyphicon-eye-open"></i> {{post.views}}</span>

<span class="item article-meta-comment" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="評論量">

<i class="glyphicon glyphicon-comment"></i> </span> </div>

</header>

<article class="article-content">

<p>{{post.content}}</p>

</article>

<div class="article-tags">標(biāo)簽:

{% for tag in post.tags.all %}

<a href="/tags/{{tag.id}}">{{tag.name}}</a>

{% endfor %}

</div>

{% endblock %}


# 二十未巫、實現(xiàn)相關(guān)推薦功能

*   編寫視圖

def blog_detail(request, pid):

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

post.views = post.views + 1

post.save()

comment_list = Comment.objects.order_by('-pub_date')

最新評論的博客 列表

new_comment_list = []

去重

for c in comment_list:

if c.post not in new_comment_list:

new_comment_list.append(c.post)

相關(guān)推薦

首先 我們需要取到 這篇文章的tag

tag_post_list = []

for tag in post.tags.all():

tag_post_list.extend(tag.post_set.all())

ctx = {

'post': post,

'new_comment_list': new_comment_list,

'tag_post_list': tag_post_list

}

return render(request, 'show.html', ctx)


*   模板

{% for tag_post in tag_post_list %}

<li><a href="{% url 'blog:detail' tag_post.id %}" title="">{{ tag_post.title }}</a></li>

{% endfor %}


# 二十一窿撬、實現(xiàn)發(fā)表評論的功能

  • show.html

    <h3>評論</h3>

</div>

<div id="respond">

    <form id="comment-form" name="comment-form" action="/comment/{{post.id}}" method="POST">

        <div class="comment">

            <input name="username" id="" value="{{user.username}}" class="form-control" size="22" placeholder="您的昵稱(必填)" maxlength="15" autocomplete="off" tabindex="1" type="text">

            <!-- <input name="" id="" class="form-control" size="22" placeholder="您的網(wǎng)址或郵箱(非必填)" maxlength="58" autocomplete="off" tabindex="2" type="text"> -->

            <div class="comment-box">

                <textarea placeholder="您的評論或留言(必填)" name="content" id="comment-textarea" cols="100%" rows="3" tabindex="3"></textarea>

                <div class="comment-ctrl">

                    <div class="comment-prompt" style="display: none;"> <i class="fa fa-spin fa-circle-o-notch"></i> <span class="comment-prompt-text">評論正在提交中...請稍后</span> </div>

                    <div class="comment-success" style="display: none;"> <i class="fa fa-check"></i> <span class="comment-prompt-text">評論提交成功...</span> </div>

                    <button type="submit" name="comment-submit" id="comment-submit" tabindex="4">評論</button>

                </div>

            </div>

        </div>

{% csrf_token %}

    </form>

*   編寫視圖類

class CommentView(View):

def get(self, request):

pass

def post(self, request, bid):

comment = Comment()

comment.user = request.user

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

comment.content = request.POST.get('content')

comment.pub_date = datetime.now()

comment.save()

Ajax

return HttpResponseRedirect(reverse("blog_detail", kwargs={"bid":bid}))


*   編寫路由

url(r'^comment/(?P<bid>[0-9]+)$', CommentView.as_view(), name='comment'),


# 二十二、實現(xiàn)評論列表功能

*   編寫視圖

def blog_detail(request,bid):

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

post.views = post.views + 1

post.save()

最新評論博客

new_comment_list = Comment.objects.order_by('-pub_date').all()[:10]

comment_list = post.comment_set.all()

去重

new_comment_list1 = []

post_list1 = []

for c in new_comment_list:

if c.post.id not in post_list1:

new_comment_list1.append(c)

post_list1.append(c.post.id)

博客標(biāo)簽

tag_list = post.tags.all()

相關(guān)推薦(標(biāo)簽相同的)

post_recomment_list = set(Post.objects.filter(tags__in=tag_list)[:6])

ctx = {

'post': post,

'new_comment_list': new_comment_list1,

'post_recomment_list': post_recomment_list,

'comment_list': comment_list

}

return render(request, 'show.html', ctx)

{% for comment in comment_list %}

<li class="comment-content"><span class="comment-f">#{{forloop.counter}}</span><div class="comment-main"><p><a class="address" href="#" rel="nofollow" target="_blank">{{comment.user.username}}</a><span class="time">({{comment.pub_date|date:'Y-m-d'}})</span><br>{{comment.content}}</p></div></li>

{% endfor %}


# 二十三叙凡、實現(xiàn)登錄功能

# 二十四劈伴、實現(xiàn)注冊功能

# 二十五、實現(xiàn)注冊驗證功能

# 二十六握爷、實現(xiàn)注銷功能

# 二十七跛璧、實現(xiàn)后臺富文本功能















?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市饼拍,隨后出現(xiàn)的幾起案子赡模,更是在濱河造成了極大的恐慌,老刑警劉巖师抄,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漓柑,死亡現(xiàn)場離奇詭異,居然都是意外死亡叨吮,警方通過查閱死者的電腦和手機辆布,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茶鉴,“玉大人锋玲,你說我怎么就攤上這事『#” “怎么了惭蹂?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長割粮。 經(jīng)常有香客問我盾碗,道長,這世上最難降的妖魔是什么舀瓢? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任廷雅,我火速辦了婚禮,結(jié)果婚禮上京髓,老公的妹妹穿的比我還像新娘航缀。我一直安慰自己,他們只是感情好堰怨,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布芥玉。 她就那樣靜靜地躺著,像睡著了一般备图。 火紅的嫁衣襯著肌膚如雪飞傀。 梳的紋絲不亂的頭發(fā)上皇型,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機與錄音砸烦,去河邊找鬼弃鸦。 笑死,一個胖子當(dāng)著我的面吹牛幢痘,可吹牛的內(nèi)容都是我干的唬格。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼颜说,長吁一口氣:“原來是場噩夢啊……” “哼购岗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起门粪,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤喊积,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后玄妈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乾吻,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年拟蜻,在試婚紗的時候發(fā)現(xiàn)自己被綠了绎签。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡酝锅,死狀恐怖诡必,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搔扁,我是刑警寧澤爸舒,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站稿蹲,受9級特大地震影響扭勉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜场绿,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一剖效、第九天 我趴在偏房一處隱蔽的房頂上張望嫉入。 院中可真熱鬧焰盗,春花似錦、人聲如沸咒林。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垫竞。三九已至澎粟,卻和暖如春蛀序,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背活烙。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工徐裸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人啸盏。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓重贺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親回懦。 傳聞我的和親對象是個殘疾皇子气笙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容