Django博客项目之个人站点

一、对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>&nbsp;&nbsp;&nbsp;&nbsp;
                                        <span class="glyphicon glyphicon-comment"
                                              style="color: #1b6d85;vertical-align: -3px"></span>评论({{ article.comment_count }})&nbsp;&nbsp;
                                        <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>&nbsp;&nbsp;&nbsp;&nbsp;
                            <span class="glyphicon glyphicon-comment"
                                  style="color: #1b6d85;vertical-align: -3px"></span>评论({{ article.comment_count }})&nbsp;&nbsp;
                            <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

时间: 2024-09-30 10:36:44

Django博客项目之个人站点的相关文章

Django博客项目之首页

一.Django-admin 1.创建表和注册表 settings.py文件: TIME_ZONE = 'Asia/Shanghai'    #支持中文数据 models.py文件内容: from django.db import models from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser):     """     用户信息     ""&q

Django——博客项目

博客项目 目前的目标是构建一个基于Django的前后端完整的博客系统,首先对项目流程整理如下: 1. 分析需求 1.1. 1.基于用户认证组件和Ajax实现登录验证 1.2. 基于forms组件和Ajax实现注册功能 1.3. 设计系统首页(文章列表渲染) 1.4. 设计个人站点页面 1.5. 文章详情页 1.6. 实现文章点赞功能 1.7. 实现文章的评论 1.7.1. 文章的评论 1.7.2. 评论的评论 1.8. 富文本编辑框和防止xss攻击 2. 设计表结构 module代码: from

Django博客项目之登录和注册系统

一.环境准备 1.配置文件 settings.py文件: 增加一项内容实现UserInfo表继承Django用户认证的表 AUTH_USER_MODEL="blog.UserInfo" TEMPLATES = [     {         'BACKEND': 'django.template.backends.django.DjangoTemplates',         'DIRS': [os.path.join(BASE_DIR, 'templates')]         

django -&gt; 博客项目sqlite数据迁移至mysql

准备: 云服务器上安装mysql 本地虚拟环境安装mysqlclient(下载地址): python -m pip install  mysqlclient-1.4.4-cp36-cp36m-win_amd64.whl mysql数据设置 # root账号登录 mysql -u root -p # 创建数据库 — mysite_db create database mysite_db default charset=utf8mb4 default collate utf8mb4_unicode_

Django博客项目之表关系设计

一.需要创建的表以及表之间的关系 1.User(用户信息表) User表和Blog表是一对一关系,即一个用户对应一个个人站点 2.Blog(个人站点表) 3.Category(文章分类表) Blog和Category表是一对多关系,即一个站点可以有多个分类,但是一个分类只属于一个站点 4.Tag(文章标签表) Blog和Tag表是一对多关系,即一个站点可以有多个标签,但是一个标签只属于一个站点 5.Article(文章表) User和Article表是一对多关系,即一个用户可以有多篇文章,但是一

Django学习---多人博客项目(2)

Django学习---多人博客项目(2) ? 上一部分内容完成了博客项目的搭建,以及博客标题和博客内容的展示,熟悉了Django的使用,下面,接着实现用户管理部分功能. 一.自定义模板和静态文件的位置 (1)自定义模板的位置 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 当前文件路径的上两级文件路径--即是根目录 TEMPLATES = [ { 'BACKEND': 'django.templat

Django 博客实现简单的全文搜索

作者:HelloGitHub-追梦人物 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 搜索是一个复杂的功能,但对于一些简单的搜索任务,我们可以使用 Django Model 层提供的一些内置方法来完成.现在我们来为我们的博客提供一个简单的搜索功能. 概述 博客文章通常包含标题和正文两个部分.当用户输入某个关键词进行搜索后,我们希望为用户显示标题和正文中含有被搜索关键词的全部文章.整个搜索的过程如下: 用户在搜素框中输入搜索关键词,假设为 "django",

博客项目实现文章评论功能(重点是评论回复)

我开发的博客网站的地址:http://118.89.29.170/RiXiang_blog/ 博客项目代码github:https://github.com/SonnAdolf/sonne_blog 有了我的已成型的项目和代码,可以更容易理解这篇文章. 本篇文章记录下自己博客项目评论功能实现的全过程,重点其实是评论回复功能. [一,写评论] 写评论部分我没有使用富文本编辑器,只是单纯地使用了textarea标签,所以后台不需要作html标签的白名单检验(关于防范xss攻击,可以看我之前的一篇文章

建立django博客应用及数据库模型

1.现在就来创建我们的 Django 博客应用,我把它命名为 blog.激活虚拟环境,进入到 manage.py 文件所在的目录下,运行 python manage.py startapp blog 命令即可建立一个 blog 应用 这个应用的文件夹结构 Django 已经为我们建立好了,但它还只是包含各种文件的一个文件夹而已,Django 目前还不知道这是一个应用.我们得告诉 Django 这是我们建立的应用,专业一点说就是在 Django 的配置文件中注册这个应用.打开 blogprojec