zoukankan      html  css  js  c++  java
  • 博客当中的文章分类以及归档

    博客当中侧栏一般都会有分类、标签、日期等,一般博主会根据这些将博客归类,并且点击后,会显示出归类好的文章列表。

    需要使用的技术为model中的annotate,相当于mysql中的group by

    例:

    django中的model

    from django.db import models
    
    from django.contrib.auth.models import (
        BaseUserManager, AbstractBaseUser, AbstractUser
    )
    
    
    # class MyUserManager(BaseUserManager):
    #     def create_user(self, email, name, password=None):
    #         """
    #         Creates and saves a User with the given email, date of
    #         birth and password.
    #         """
    #         if not email:
    #             raise ValueError('Users must have an email address')
    #
    #         user = self.model(
    #             email=self.normalize_email(email),
    #             name=name,
    #         )
    #
    #         user.set_password(password)
    #         user.save(using=self._db)
    #         return user
    #
    #     def create_superuser(self, email, name, password):
    #         """
    #         Creates and saves a superuser with the given email, date of
    #         birth and password.
    #         """
    #         user = self.create_user(
    #             email,
    #             password=password,
    #             name=name,
    #         )
    #         user.is_admin = True
    #         user.save(using=self._db)
    #         return user
    #
    #
    # class MyUser(AbstractBaseUser):
    #     email = models.EmailField(
    #         verbose_name='email address',
    #         max_length=255,
    #         unique=True,
    #     )
    #     # date_of_birth = models.DateField()
    #     name = models.CharField(max_length=32)
    #     is_active = models.BooleanField(default=True)
    #     is_admin = models.BooleanField(default=False)
    #
    #     objects = MyUserManager()
    #
    #     USERNAME_FIELD = 'email'
    #     REQUIRED_FIELDS = ['name']
    #
    #     def __str__(self):
    #         return self.email
    #
    #     def has_perm(self, perm, obj=None):
    #         "Does the user have a specific permission?"
    #         # Simplest possible answer: Yes, always
    #         return True
    #
    #     def has_module_perms(self, app_label):
    #         "Does the user have permissions to view the app `app_label`?"
    #         # Simplest possible answer: Yes, always
    #         return True
    #
    #     @property
    #     def is_staff(self):
    #         "Is the user a member of staff?"
    #         # Simplest possible answer: All admins are staff
    #         return self.is_admin
    
    # class UserInfo(AbstractBaseUser):
    #
    #     avatar = models.ImageField(upload_to="img")
    #
    # class Blog(models.Model):
    #     info = models.CharField()
    #
    # class Artical(models.Model):
    #     title = models.CharField(max_length=128)
    #     publish_date = models.DateTimeField()
    #     author = models.ForeignKey(UserInfo, on_delete=models.CASCADE)
    #     content = models.OneToOneField(Blog, on_delete=models.CASCADE)
    #
    # class Commments(models.Model):
    #     user = models.ForeignKey(UserInfo, on_delete=models.CASCADE)
    #     c_time = models.DateTimeField()
    #     comments = models.CharField()
    #     artical = models.ForeignKey(Artical, on_delete=models.CASCADE)
    #     reply = models.ForeignKey("Commments", on_delete=models.CASCADE)
    #
    # class Tag(models.Model):
    #     tag_name = models.CharField()
    #     artical = models.ManyToManyField(Artical)
    #
    # class Category(models.Model):
    #     name = models.CharField(max_length=64)
    #     artical = models.ManyToManyField(Artical)
    #
    # class Praise(models.Model):
    #     tag = models.IntegerField()
    #     artical = models.ForeignKey(Artical, on_delete=models.CASCADE)
    #     user = models.ForeignKey(UserInfo, on_delete=models.CASCADE)
    
    class UserInfo(AbstractUser):
        """
        用户信息表
        """
        nid = models.AutoField(primary_key=True)
        phone = models.CharField(max_length=11, null=True, unique=True)
        avatar = models.FileField(upload_to="avatars/", default="avatars/default.png", verbose_name="头像")
        create_time = models.DateTimeField(auto_now_add=True)
    
        blog = models.OneToOneField(to="Blog", to_field="nid", null=True, on_delete=models.CASCADE)
    
        def __str__(self):
            return self.username
    
        # class Meta:
        #     verbose_name="用户"
        #     verbose_name_plural=verbose_name
    
    
    class Blog(models.Model):
        """
        博客信息
        """
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=64)  # 个人博客标题
        site = models.CharField(max_length=32, unique=True)  # 个人博客后缀
        theme = models.CharField(max_length=32)  # 博客主题
    
        def __str__(self):
            return self.title
    
        class Meta:
            verbose_name="博客信息"
            verbose_name_plural=verbose_name
    
    
    class Category(models.Model):
        """
        个人博客文章分类
        """
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)  # 分类标题
        blog = models.ForeignKey(to="Blog", to_field="nid", on_delete=models.CASCADE)  # 外键关联博客,一个博客站点可以有多个分类
    
        def __str__(self):
            return self.title
    
        class Meta:
            verbose_name="分类"
            verbose_name_plural=verbose_name
    
    class Tag(models.Model):
        """
        标签
        """
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)  # 标签名
        blog = models.ForeignKey(to="Blog", to_field="nid", on_delete=models.CASCADE)  # 所属博客
    
        def __str__(self):
            return self.title
    
        class Meta:
            verbose_name="标签"
            verbose_name_plural=verbose_name
    
    class Article(models.Model):
        """
        文章
        """
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=50)  # 文章标题
        desc = models.CharField(max_length=255)  # 文章描述
        create_time = models.DateTimeField()  # 创建时间
    
        category = models.ForeignKey(to="Category", to_field="nid", null=True, on_delete=models.CASCADE)
        user = models.ForeignKey(to="UserInfo", to_field="nid", on_delete=models.CASCADE)
        tags = models.ManyToManyField(  # 中介模型
            to="Tag",
            through="Article2Tag",
            through_fields=("article", "tag"),  # 注意顺序!!!
        )
    
        comment_count = models.IntegerField(verbose_name="评论数", default=0)
        updown = models.IntegerField(verbose_name="点赞数", default=0)
    
        def __str__(self):
            return self.title
    
        class Meta:
            verbose_name="文章"
            verbose_name_plural=verbose_name
    
    
    class ArticleDetail(models.Model):
        """
        文章详情表
        """
        nid = models.AutoField(primary_key=True)
        content = models.TextField()
        article = models.OneToOneField(to="Article", to_field="nid", on_delete=models.CASCADE)
    
        class Meta:
            verbose_name="文章内容"
            verbose_name_plural=verbose_name
    
        def __str__(self):
            return ("{}".format(self.article.title))
    
    
    class Article2Tag(models.Model):
        """
        文章和标签的多对多关系表
        """
        nid = models.AutoField(primary_key=True)
        article = models.ForeignKey(to="Article", to_field="nid", on_delete=models.CASCADE)
        tag = models.ForeignKey(to="Tag", to_field="nid", on_delete=models.CASCADE)
    
        class Meta:
            unique_together = (("article", "tag"),)
            verbose_name="文章-标签"
            verbose_name_plural=verbose_name
    
        # 给返回对象赋值,否则前端看见的均为"Article2Tag object(n)"
        def __str__(self):
            return "{}-{}".format(self.article.title, self.tag.title)
    
    
    class ArticleUpDown(models.Model):
        """
        点赞表
        """
        nid = models.AutoField(primary_key=True)
        user = models.ForeignKey(to="UserInfo", null=True, on_delete=models.CASCADE)
        article = models.ForeignKey(to="Article", null=True, on_delete=models.CASCADE)
        is_up = models.BooleanField(default=True)
    
        class Meta:
            unique_together = (("article", "user"),)
            verbose_name="点赞"
            verbose_name_plural=verbose_name
    
    
    class Comment(models.Model):
        """
        评论表
        """
        nid = models.AutoField(primary_key=True)
        article = models.ForeignKey(to="Article", to_field="nid", on_delete=models.CASCADE)
        user = models.ForeignKey(to="UserInfo", to_field="nid", on_delete=models.CASCADE)
        content = models.CharField(max_length=255)  # 评论内容
        create_time = models.DateTimeField(auto_now_add=True)
        parent_comment = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE)
    
        def __str__(self):
            return self.content
    
        class Meta:
            verbose_name="评论"
            verbose_name_plural=verbose_name
    models.py

    路由设置:

    project下的路由

    """Hero URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/2.1/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  path('', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.urls import include, path
        2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    """
    from django.contrib import admin
    from django.urls import path, re_path, include
    from jax import views
    
    from django.views.static import serve
    from django.conf import settings
    
    from jax import urls as jax_urls
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('backend/', views.backend),
        re_path('artical-(?P<artical_type_id>d+)-(?P<category_id>d+).html', views.artical),
        path('login/', views.login),
        path('logout/', views.logout),
        path('index/', views.index),
        path('register/', views.register),
        path('reg/', views.reg),
        path('check_code.html', views.check_code),
        path('check_username_exist/', views.check_username_exist),
        path('blog/', include(jax_urls)),
    
        # media相关的路由设置
        re_path(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}),
    ]
    urls.py

    app下的路由

    from jax import views
    from django.urls import path, re_path
    
    urlpatterns = [
        re_path('(?P<username>w+)/p/(?P<pk>d+).html', views.artical_detail),
    
        #文章筛选,传递的参数为用户名、筛选条件(category、tag)、筛选条件的id(cta=category、tag)
        re_path('(?P<username>w+)/(?P<screening>w+)/(?P<screening_cta_id>w+).html', views.artical_screening),
        # 文章筛选,筛选出指定月份的文章,d{4}代表匹配4个数字,d{2}代表匹配2个数字
        re_path('(?P<username>w+)/(?P<screening>w+)/(?P<screening_cta_id>d{4}-d{2}).html', views.artical_screening),
        re_path('(w+)', views.home),
    ]
    urls.py

    显示博客当中所有用户的文章列表:

    一般博客的前端分配比例为左侧略少,显示分类,右侧偏宽,显示文章列表或者文章内容,这里选用bootstrap当中的"col-md-n",页面分为12列,左侧col-md-3,右侧col-md-9,放在div.container和div.row中。"font-awesome"作为评论或者赞的图标。

    def index(request):
        # print(request.user.username)
        artical_list = models.Article.objects.all()
        username = ""
        return render(request, "index.html", {
            "artical_list": artical_list,
        })
    View Code
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
        <link rel="stylesheet" href="/static/css/backend.css">
        <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    </head>
    <body>
        <nav class="navbar navbar-default">
            <div class="container-fluid">
                <!-- Brand and toggle get grouped for better mobile display -->
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                            data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="/index/">博客</a>
                </div>
    
                <!-- Collect the nav links, forms, and other content for toggling -->
                <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                    <ul class="nav navbar-nav">
                        <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                        <li><a href="#">Link</a></li>
                        <li class="dropdown">
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                               aria-expanded="false">Dropdown <span class="caret"></span></a>
                            <ul class="dropdown-menu">
                                <li><a href="#">Action</a></li>
                                <li><a href="#">Another action</a></li>
                                <li><a href="#">Something else here</a></li>
                                <li role="separator" class="divider"></li>
                                <li><a href="#">Separated link</a></li>
                                <li role="separator" class="divider"></li>
                                <li><a href="#">One more separated link</a></li>
                            </ul>
                        </li>
                    </ul>
                    <form class="navbar-form navbar-left">
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="Search">
                        </div>
                        <button type="submit" class="btn btn-default">Submit</button>
                    </form>
                    <ul class="nav navbar-nav navbar-right">
                        {% if request.user.username %}
                            <li><a href="#">{{ request.user.username }}</a></li>
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                                   aria-expanded="false">个人中心<span class="caret"></span></a>
                                <ul class="dropdown-menu">
                                    <li><a href="#">Action</a></li>
                                    <li><a href="#">Another action</a></li>
                                    <li><a href="#">Something else here</a></li>
                                    <li role="separator" class="divider"></li>
                                    <li><a href="/logout/">注销</a></li>
                                </ul>
                            </li>
                        {% else %}
                            <li><a href="/login/">登陆</a></li>
                            <li><a href="/register/">注册</a></li>
                        {% endif %}
                    </ul>
                </div><!-- /.navbar-collapse -->
            </div><!-- /.container-fluid -->
        </nav>
    
        <div class="container">
            <div class="row">
                <div class="col-md-3">
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            文章分类
                        </div>
                        <div class="panel-body">
                            {% for category in category_list %}
                                <p><a href="#">{{ category.title }}({{ category.c }})</a></p>
                            {% endfor %}
    
                        </div>
                    </div>
                    <div class="panel panel-info">
                        <div class="panel-heading">
                            文章标签
                        </div>
                        <div class="panel-body">
                            {% for tag in tag_list %}
                                <p><a href="#">{{ tag.title }}({{ tag.c }})</a></p>
                            {% endfor %}
    
                        </div>
                    </div>
                    <div class="panel panel-warning">
                        <div class="panel-heading">
                            文章日期
                        </div>
                        <div class="panel-body">
                            {% for archive in archive_list %}
                                <p><a href="#">{{ archive.archive_ym }}({{ archive.c }})</a></p>
                            {% endfor %}
                        </div>
                    </div>
                </div>
                <div class="col-md-9">
                    {% for artical in artical_list %}
                        <div>
                            <h3><a href="/blog/{{ artical.user.username }}/p/{{ artical.pk }}.html">{{ artical }}</a></h3>
                            <div class="media">
                                <div class="media-left">
                                    <a href="#">
                                        <img class="media-object avatars-img" src="/media/{{ artical.user.avatar }}"
                                             alt="...">
                                    </a>
                                </div>
                                <div class="media-body">
                                    {{ artical.desc }}
                                </div>
                                <div style="float: right;">
                                    <div class="artical-footer">
                                        <span><a href="/blog/{{ artical.user }}">{{ artical.user }}</a> </span>发布于
                                        <span>{{ artical.create_time|date:'Y-m-d H:i:s' }}</span>
                                        {#                                <span class="glyphicon glyphicon-comment"><a href="#">评论({{ artical.comment_count }})</a></span>#}
                                        {#                                <span class="glyphicon glyphicon-thumbs-up"><a href="#">点赞({{ artical.updown }})</a> </span>#}
                                        <span><i class="fa fa-comment-o" aria-hidden="true"><a
                                                href="#">评论({{ artical.comment_count }})</a></i></span>
                                        <span><i class="fa fa-thumbs-o-up" aria-hidden="true"><a
                                                href="#">点赞({{ artical.updown }})</a></i></span>
                                        <span>{{ artical.category }}</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    {% endfor %}
                </div>
            </div>
        </div>
    
        <script type="application/javascript" src="/static/bootstrap-3.3.7-dist/js/jquery-1.12.4.js"></script>
        <script type="application/javascript" src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    </body>
    </html>
    index.html

    设计思路:

      每个博客下面都显示着文章的作者,当点击文章标题要显示文章内容,点击作者要显示作者的所有文章,并且点击后,页面左侧都会将作者的所有分类、归档的文章数量显示在左侧标题栏。不过,这里首先要把作者的所有博客全都给分组。

    这里使用annotate分组

    def get_left_menu(username):
        user = models.UserInfo.objects.filter(username=username).first()
        blog = user.blog # 每一个user都有一个blog名称,相当于博客园当中自己起的名字,每个blog.title下面都有自己的分组和tag
    
        from django.db.models import Count
    
        # 将文章按照分组分类,并且统计出个数
        category_list = models.Category.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c", "nid")
        # category_list2 = models.Category.objects.filter(blog=blog).annotate(c=Count("article"))
        # print(category_list2.values())
        # 将所有文章按照标签分类,并统计个数
        tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c", "nid")
    
        # 将所有文章按照日期归档,sqlite数据书需要使用strftime('%Y-%m-%d %H:%M:%S', 'now')函数,mysql函数需要使用date_format('now', '%Y-%m-%d %H:%M:%S')函数
        archive_list = models.Article.objects.filter(user=user).extra(
            select={"archive_ym": "strftime('%%Y-%%m', create_time)"}
        ).values("archive_ym").annotate(c=Count("nid")).values("archive_ym", "c")
    
        return {
            "category_list": category_list,
            "tag_list": tag_list,
            "archive_list": archive_list,
            "username": username,
        }
    View Code
    from jax import models
    from django import template
    
    
    register = template.Library()
    
    @register.inclusion_tag("blog_left_menu.html")
    def get_left_menu(username):
        user = models.UserInfo.objects.filter(username=username).first()
        blog = user.blog # 每一个user都有一个blog名称,相当于博客园当中自己起的名字,每个blog.title下面都有自己的分组和tag
    
        from django.db.models import Count
    
        # 将文章按照分组分类,并且统计出个数
        category_list = models.Category.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c", "nid")
        # category_list2 = models.Category.objects.filter(blog=blog).annotate(c=Count("article"))
        # print(category_list2.values())
        # 将所有文章按照标签分类,并统计个数
        tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c", "nid")
    
        # 将所有文章按照日期归档,sqlite数据书需要使用strftime('%Y-%m-%d %H:%M:%S', 'now')函数,mysql函数需要使用date_format('now', '%Y-%m-%d %H:%M:%S')函数
        # extra参数是额外执行sql命令,这里相当于给对象新添加了一个字段"archive_ym",每一行中该字段由strftime('%%Y-%%m', create_time)"赋值
        archive_list = models.Article.objects.filter(user=user).extra(
            select={"archive_ym": "strftime('%%Y-%%m', create_time)"}
        ).values("archive_ym").annotate(c=Count("nid")).values("archive_ym", "c")
    
        return {
            "category_list": category_list,
            "tag_list": tag_list,
            "archive_list": archive_list,
            "username": username,
        }
    
        # annotate前面是什么,就按照什么分组,至于annotate里面定义的变量,名字自起,这里为c,后面需要使用Count或Avg这种参数来对括号里面的变量求值,里面的值可以是一个其他的表,也可以是本身自己表的字段之一,取得的统计值会作为一个{"key": "value"}封装到对象当中,可以通过values参数来获取值
    get_left_menu.html

    由于左侧导航栏的样式不变,可以将该内容单独拿出作为一个模板,同时为了前端页面的整洁,可以将获取左侧导航栏内容和方法的方法添加到app/templatetags目录当中。创建一个基础模板,将博客左侧的内容和右侧的内容单独拿出,将他们作为一个block来修改。

    from jax import models
    from django import template
    
    
    register = template.Library()
    
    @register.inclusion_tag("blog_left_menu.html")
    def get_left_menu(username):
        user = models.UserInfo.objects.filter(username=username).first()
        blog = user.blog # 每一个user都有一个blog名称,相当于博客园当中自己起的名字,每个blog.title下面都有自己的分组和tag
    
        from django.db.models import Count
    
        # 将文章按照分组分类,并且统计出个数
        category_list = models.Category.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c", "nid")
        # category_list2 = models.Category.objects.filter(blog=blog).annotate(c=Count("article"))
        # print(category_list2.values())
        # 将所有文章按照标签分类,并统计个数
        tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c", "nid")
    
        # 将所有文章按照日期归档,sqlite数据书需要使用strftime('%Y-%m-%d %H:%M:%S', 'now')函数,mysql函数需要使用date_format('now', '%Y-%m-%d %H:%M:%S')函数
        # extra参数是额外执行sql命令,这里相当于给对象新添加了一个字段"archive_ym",每一行中该字段由strftime('%%Y-%%m', create_time)"赋值
        archive_list = models.Article.objects.filter(user=user).extra(
            select={"archive_ym": "strftime('%%Y-%%m', create_time)"}
        ).values("archive_ym").annotate(c=Count("nid")).values("archive_ym", "c")
    
        return {
            "category_list": category_list,
            "tag_list": tag_list,
            "archive_list": archive_list,
            "username": username,
        }
    
        # annotate前面是什么,就按照什么分组,至于annotate里面定义的变量,名字自起,这里为c,后面需要使用Count或Avg这种参数来对括号里面的变量求值,里面的值可以是一个其他的表,也可以是本身自己表的字段之一,取得的统计值会作为一个{"key": "value"}封装到对象当中,可以通过values参数来获取值
    blog_left_menu.py
    <div class="panel panel-primary">
        <div class="panel-heading">
            文章分类
        </div>
        <div class="panel-body">
            {% for category in category_list %}
                <p><a href="/blog/{{ username }}/category/{{ category.nid}}.html">{{ category.title }}({{ category.c }})</a></p>
            {% endfor %}
    
        </div>
    </div>
    <div class="panel panel-info">
        <div class="panel-heading">
            文章标签
        </div>
        <div class="panel-body">
            {% for tag in tag_list %}
                <p><a href="/blog/{{ username }}/tag/{{ tag.nid }}.html">{{ tag.title }}({{ tag.c }})</a></p>
            {% endfor %}
    
        </div>
    </div>
    <div class="panel panel-warning">
        <div class="panel-heading">
            文章日期
        </div>
        <div class="panel-body">
            {% for archive in archive_list %}
                <p><a href="/blog/{{ username }}/archive/{{ archive.archive_ym }}.html">{{ archive.archive_ym }}({{ archive.c }})</a></p>
            {% endfor %}
        </div>
    </div>
    blog_left_menu.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
        <link rel="stylesheet" href="/static/css/backend.css">
        <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    </head>
    <body>
        <nav class="navbar navbar-default">
            <div class="container-fluid">
                <!-- Brand and toggle get grouped for better mobile display -->
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                            data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="/index/">博客</a>
                </div>
    
                <!-- Collect the nav links, forms, and other content for toggling -->
                <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                    <ul class="nav navbar-nav">
                        <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                        <li><a href="#">Link</a></li>
                        <li class="dropdown">
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                               aria-expanded="false">Dropdown <span class="caret"></span></a>
                            <ul class="dropdown-menu">
                                <li><a href="#">Action</a></li>
                                <li><a href="#">Another action</a></li>
                                <li><a href="#">Something else here</a></li>
                                <li role="separator" class="divider"></li>
                                <li><a href="#">Separated link</a></li>
                                <li role="separator" class="divider"></li>
                                <li><a href="#">One more separated link</a></li>
                            </ul>
                        </li>
                    </ul>
                    <form class="navbar-form navbar-left">
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="Search">
                        </div>
                        <button type="submit" class="btn btn-default">Submit</button>
                    </form>
                    <ul class="nav navbar-nav navbar-right">
                        {% if request.user.username %}
                            <li><a href="#">{{ request.user.username }}</a></li>
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                                   aria-expanded="false">个人中心<span class="caret"></span></a>
                                <ul class="dropdown-menu">
                                    <li><a href="#">Action</a></li>
                                    <li><a href="#">Another action</a></li>
                                    <li><a href="#">Something else here</a></li>
                                    <li role="separator" class="divider"></li>
                                    <li><a href="/logout/">注销</a></li>
                                </ul>
                            </li>
                        {% else %}
                            <li><a href="/login/">登陆</a></li>
                            <li><a href="/register/">注册</a></li>
                        {% endif %}
                    </ul>
                </div><!-- /.navbar-collapse -->
            </div><!-- /.container-fluid -->
        </nav>
    
        <div class="container">
            <div class="row">
                <div class="col-md-3">
                    {% load blog_left_menu %}   <!--导入templatetags目录当中的文件-->
    
                    {% get_left_menu username %}    <!--引用所倒入文件blog_left_menu.py中的get_left_menu方法,并且提供username作为参数}-->
                </div>
                <div class="col-md-9">
                    {% block page_main %}
                    {% endblock %}
                </div>
            </div>
        </div>
    
        <script type="application/javascript" src="/static/bootstrap-3.3.7-dist/js/jquery-1.12.4.js"></script>
        <script type="application/javascript" src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    </body>
    </html>
    base.html

    然后创建一个能够extends base.html板的页面,对博客右侧的内容同过block做渲染。

    {% extends "base.html" %}
    
    {% block page_main %}
        {% for artical in artical_list %}
            <div>
                <h3><a href="/blog/{{ artical.user.username }}/p/{{ artical.pk }}.html">{{ artical }}</a></h3>
                <div class="media">
                    <div class="media-left">
                        <a href="#">
                            <img class="media-object avatars-img" src="/media/{{ artical.user.avatar }}" alt="...">
                        </a>
                    </div>
                    <div class="media-body">
                        {{ artical.desc }}
                    </div>
                    <div style="float: right;">
                        <div class="artical-footer">
                            <span><a href="/blog/{{ artical.user }}">{{ artical.user }}</a> </span>发布于
                            <span>{{ artical.create_time|date:'Y-m-d H:i:s' }}</span>
                            {#                                <span class="glyphicon glyphicon-comment"><a href="#">评论({{ artical.comment_count }})</a></span>#}
                            {#                                <span class="glyphicon glyphicon-thumbs-up"><a href="#">点赞({{ artical.updown }})</a> </span>#}
                            <span><i class="fa fa-comment-o" aria-hidden="true"><a
                                    href="#">评论({{ artical.comment_count }})</a></i></span>
                            <span><i class="fa fa-thumbs-o-up" aria-hidden="true"><a
                                    href="#">点赞({{ artical.updown }})</a></i></span>
                            <span>{{ artical.category }}</span>
                        </div>
                    </div>
                </div>
            </div>
        {% endfor %}
    {% endblock %}
    home.html
    显示文章的路由:
    re_path('(?P<username>w+)/p/(?P<pk>d+).html', views.artical_detail),

     以上内容做完后,在博客首页点击博客title会显示博客所有的内容,点击用户名,会显示该用户的博客列表,并且博客页面左侧会显示分类。这里需要思考前端分类变迁中href的路由以及后台urls.py路由如何匹配:

        #文章筛选,传递的参数为用户名、筛选条件(category、tag)、筛选条件的id(cta=category、tag)
        re_path('(?P<username>w+)/(?P<screening>w+)/(?P<screening_cta_id>w+).html', views.artical_screening),
        # 文章筛选,筛选出指定月份的文章,d{4}代表匹配4个数字,d{2}代表匹配2个数字
        re_path('(?P<username>w+)/(?P<screening>w+)/(?P<screening_cta_id>d{4}-d{2}).html', views.artical_screening),
        re_path('(w+)', views.home),
    urls.py
    def artical_screening(request, username, screening, screening_cta_id):
        user = models.UserInfo.objects.filter(username=username).first()
    
        if screening == "category": # 如果用户点击的是catgory
            # category_list1 = models.Article.objects.filter(user=user)
            c = models.Category.objects.filter(nid=screening_cta_id).first()
            artical_list = models.Article.objects.filter(user=user, category=c)
        if screening == "tag":  # 如果用户点击的是tag
            t = models.Tag.objects.filter(nid=screening_cta_id).first()
            artical_list = models.Article.objects.filter(user=user, tags=t)
        if screening == "archive": # 如果用户点击的是archive
            # 将url传递过来的日期分割,切割条件为"-"
            create_time = screening_cta_id.split("-")
            artical_list = models.Article.objects.filter(user=user, create_time__year=create_time[0], create_time__month=create_time[1])
    
        return render(request, "home.html", {
            "artical_list": artical_list,
            "username": username,
        })
    views.py
  • 相关阅读:
    几个论坛上看到的2015小米笔试题
    Line(扩展欧几里得)
    MapReduce编程之倒排索引
    annotation(@Retention@Target)详解
    【JEECG技术文档】JEECG平台对外接口JWT应用文档V3.7.2
    jeecg 模糊查询
    jeecg下实现自动默认模糊查询
    The packaging for this project did not assign a file to the build artifact
    Maven添加本地Jar包
    maven 如何引入本地jar包
  • 原文地址:https://www.cnblogs.com/ttyypjt/p/10650778.html
Copyright © 2011-2022 走看看