标签:个人站点 文章页面
一、对url做分发项目cnblog_s20的urls.py内容:
from django.conf.urls import url,include
from django.contrib import admin
from blog import views
from django.views.static import serve
from cnblog_s20 import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^reg/', views.reg),
url(r'^logout/', views.logout),
url(r'^valid_img/', views.valid_img),
url(r'^index/', views.index),
url(r'^$', views.index),
url(r'^blog/', include("blog.urls")), #做分发,访问blog做分发
# media 配置
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]应用的urls.py内容:
from django.conf.urls import url, include from django.contrib import admin from blog import views from django.views.static import serve from cnblog_s20 import settings urlpatterns = [ url(r'^(?P<username>\w+)/$',views.homesite), url(r'^(?P<username>\w+)/(?P<condition>tag|cate|achrive)/(?P<params>.*)',views.homesite), url(r'^(?P<username>\w+)/articels/(?P<article_id>\d+)',views.article_detail), ]
二、日期归档
1、数据库类型
表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR
date类型-------> 2018-05-01 time类型-------> 19:42:22 datetime类型-------> 2018-05-01 19:42:22 MySQL对应的方法: date_format sqlite对应的方法 :striftime
2、extra
extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
有些情况下,Django的查询语法难以简单的表达复杂的 WHERE 子句,对于这种情况, Django 提供了 extra() QuerySet修改机制 — 它能在 QuerySet生成的SQL从句中注入新子句
(1)参数之select
The select 参数可以让你在 SELECT 从句中添加其他字段信息,它应该是一个字典,存放着属性名到 SQL 从句的映射。
queryResult=models.Article
.objects.extra(select={'is_recent': "create_time > '2018-05-05'"})
结果集中每个 Entry 对象都有一个额外的属性is_recent, 它是一个布尔值,表示 Article对象的create_time 是否晚于2018-05-05,true表示晚于2018-05-05
#sqlite数据库:
article_obj=models.Article.objects
.extra(select={"standard_time":"strftime('%%Y-%%m-%%d',create_time)"})
.values("standard_time","nid","title")
print(article_obj)
# <QuerySet [{'title': 'MongoDb 入门教程', 'standard_time': '2018-05-05', 'nid': 1}]>(2)参数之where / tables
您可以使用where定义显式SQL WHERE子句 - 也许执行非显式连接。您可以使用tables手动将表添加到SQL FROM子句。
where和tables都接受字符串列表。所有where参数均为“与”任何其他搜索条件。
queryResult=models.Article .objects.extra(where=['nid in (1,3) OR title like "py%" ','nid>2'])
3、ORM分组查询
当前站点以年月形式显示的日期以及对应的文章数
article_list=Article.objectsv.filter(user=user).extra(select={"time":"strftime('%%Y-%%m',create_time)"}).values("time").annotate(c=Count("title")).values_list("time", "c")4、表关系练习
(1)创建表关系
models.py文件内容:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=6, decimal_places=2)
create_time = models.DateField()
memo = models.CharField(max_length=32, default="")
publish = models.ForeignKey(to="Publish", default=1)
author = models.ManyToManyField("Author")
def __str__(self):
return self.title
class Publish(models.Model):
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
def __str__(self): return self.name
class AuthorDetail(models.Model):
tel = models.CharField(max_length=32)
email = models.EmailField()
author = models.OneToOneField("Author")
def __str__(self): return self.email(2)ORM分组查询
annotate():按annotate前面的select字段进行group by
多表:
Publish.objects.all().annotate(c=Count(book)).values("name", "c") #每一个出版社出版的名字和对应的书籍个数
Book.objects.all().annotate(c=Count(authors)).values("title", "c") #每一本书籍和对应的作者的个数
Author.objects.all().annotate(x=Max(book__prcie)) #每一个作者出版书籍的最高价格
单表:
Book.objects.all().values("publish").annotate(Count("title"))
ret = Article.objects.all().values("user").annotate(c=Count("title")).values("user_id", "c") #每一个作者的user_id对应的文章数
ret = Category.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c") #当前站点的每一个分类名称和对应的文章数
ret = Tag.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c") #当前站点的每一个标签名称和对应的文章数三、个人站点函数及html页面
views.py文件添加homesite视图函数:
def homesite(request,username,**kwargs):
# 查当前站点的用户对象
user=UserInfo.objects.filter(username=username).first()
# 查询当前站点对象
blog=user.blog
# 查询当前站点的所有文章,实现点击tag|cate|achrive中的a标签可以查看对应的文章
if kwargs:
condition=kwargs.get("condition") #得到url的路径类型:tag|cate|achrive其中一个
params=kwargs.get("params")
if condition=="cate":
article_list=Article.objects.filter(user=user).filter(category__title=params) # 当前站点的所有文章的分类对象
elif condition=="tag":
article_list=Article.objects.filter(user=user).filter(tags__title=params) # 当前站点的所有文章的标签对象
else:
year,month=params.split("-")
article_list=Article.objects.filter(user=user).filter(create_time__year=year,create_time__month=month) # 当前站点的所有文章的日期对象
else:
article_list=Article.objects.filter(user=user) #访问的个人站点,显示当前站点的所有文章
return render(request,"homesite.html",locals())homesite.html页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0; {#清除边距#}
padding: 0;
}
.header {
width: 100%;
height: 60px;
background-color: #369;
line-height: 60px; {#文本居住#}
}
.header .title {
font-size: 20px;
font-weight: 100;
color: white;
margin-left: 20px; {#向右偏移20px#}
}
</style>
<link rel="stylesheet" href="/static/bs/css/bootstrap.css">
<script src="/static/js/jquery-3.2.1.min.js"></script>
<script src="/static/bs/js/bootstrap.js"></script>
</head>
<body>
<div>
<p>{{ blog.title }}</p>
</div>
<div>
<div>
<div>
<div class="panel panel-warning">
<div>
<h3>我的分类</h3>
</div>
<div>
{% for cate in cate_list %}
<p><a href="/blog/{{ username }}/cate/{{ cate.0 }}">{{ cate.0 }}({{ cate.1 }})</a></p> {#分类及对应的文章数#}
{% endfor %}
</div>
</div>
<div class="panel panel-danger">
<div>
<h3>文章标签</h3>
</div>
<div>
{% for tag in tag_list %}
<p><a href="/blog/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p> {#标签及对应的文章数#}
{% endfor %}
</div>
</div>
<div class="panel panel-info">
<div>
<h3>日期归档</h3>
</div>
<div>
{% for date in date_list %}
<p><a href="/blog/{{ username }}/achrive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p>
{% endfor %}
</div>
</div>
</div>
<div>
<div>
{% for article in article_list %}
<div>
<h5><a href="/blog/{{ username}}/articels/{{ article.pk }}">{{ article.title }}</a></h5>
<div>
<div>
<div>
<div>
{{ article.desc }}
</div>
</div>
</div>
</div>
<div class="small info pull-right">
发布于
<span>{{ article.create_time|date:'Y-m-d H:i' }}</span>
<span class="glyphicon glyphicon-comment"
style="color: #1b6d85;vertical-align: -3px"></span>评论({{ article.comment_count }})
<span class="glyphicon glyphicon-thumbs-up"
style="color: #1b6d85;vertical-align: -3px"></span>点赞({{ article.up_count }})
</div>
</div>
<hr>
{% endfor %}
</div>
{% endblock %}
</div>
</div>
</div>
</body>
</html>

四、页面继承
个人站点和文章详情页面左侧部分都一样,可以用页面继承防止代码重复
base.html页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
.header {
width: 100%;
height: 60px;
background-color: #369;
line-height: 60px;
}
.header .title {
font-size: 20px;
font-weight: 100;
color: white;
margin-left: 20px;
}
</style>
<link rel="stylesheet" href="/static/bs/css/bootstrap.css">
<script src="/static/js/jquery-3.2.1.min.js"></script>
<script src="/static/bs/js/bootstrap.js"></script>
</head>
<body>
<div>
<p>{{ blog.title }}</p>
</div>
<div>
<div>
<div>
{% load my_tags %}
{% get_query_data username %}
</div>
<div>
{% block content %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>menu.html页面:
<div>
<div class="panel panel-warning">
<div>
<h3>我的分类</h3>
</div>
<div>
{% for cate in cate_list %}
<p><a href="/blog/{{ username }}/cate/{{ cate.0 }}">{{ cate.0 }}({{ cate.1 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-danger">
<div>
<h3>文章标签</h3>
</div>
<div>
{% for tag in tag_list %}
<p><a href="/blog/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-info">
<div>
<h3>日期归档</h3>
</div>
<div>
{% for date in date_list %}
<p><a href="/blog/{{ username }}/achrive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p>
{% endfor %}
</div>
</div>
</div>homesite.html页面:
{%extends "base.html" %}
{% block content %}
<div>
{% for article in article_list %}
<div>
<h5><a href="/blog/{{ username}}/articels/{{ article.pk }}">{{ article.title }}</a></h5>
<div>
<div>
<div>
<div>
{{ article.desc }}
</div>
</div>
</div>
</div>
<div class="small info pull-right">
发布于
<span>{{ article.create_time|date:'Y-m-d H:i' }}</span>
<span class="glyphicon glyphicon-comment"
style="color: #1b6d85;vertical-align: -3px"></span>评论({{ article.comment_count }})
<span class="glyphicon glyphicon-thumbs-up"
style="color: #1b6d85;vertical-align: -3px"></span>点赞({{ article.up_count }})
</div>
</div>
<hr>
{% endfor %}
</div>
{% endblock %}五、文章详情
views.py文件添加article_detail函数
def article_detail(request,username,article_id): # 查当前站点的用户对象 user = UserInfo.objects.filter(username=username).first() # 查询当前站点对象 blog = user.blog article_obj=Article.objects.filter(pk=article_id).first() #得到文章对象 return render(request,"article_detail.html",locals())
article_detail.html页面:
{% extends "base.html" %}
{% block content %}
<h3>{{ article_obj.title }}</h3> {#标题居住#}
<div>
{{ article_obj.articledetail.content|safe }}
</div>
{% endblock %}数据库保存的是标签,不加safe会显示字符串,浏览器不能成功渲染,加上safe后就可以识别标签,能够渲染页面,这样就会执行可能存在的script等标签,很不安全
所以我们必须加safe,但是要保证用户存到数据库的没有script标签,即将script标签转意或者过滤掉。

标签:个人站点 文章页面
原文地址:http://blog.51cto.com/qidian510/2120017