美文网首页
Django笔记11-分类页面与模板继承

Django笔记11-分类页面与模板继承

作者: fbckf | 来源:发表于2018-07-25 17:01 被阅读0次

    分类页面与模板继承

    显示单一类别的文章列表

    分类页面

     分类页面与首页基本相同,但是显示的是指定类别的文章

    模板

     在之前下载的模板文件中,有一个名为 category.html 的文件,将其复制到 templates/blog/ 目录下

    $ cp category.html ~/fbckf/templates/blog
    

    添加 url 规则

     分类页面的 url 是 127.0.0.1:8000/category/[分类名称]/ 这种格式

    # blog/urls.py
    from . import views
    
    app_name = 'blog'
    urlpatterns = [
        ...
        path('category/<slug>/', views.category, name='category'),
    ]
    
    

    添加视图函数

    # blog/views.py
    ...
    def category(request, slug):
        context = {}
        category = Category.objects.get(name=slug)
        context['category'] = category.name
        article_list = category.article_set.all()
        context['article_list'] = article_list
        category_list = Category.objects.all()
        context['category_list'] = category_list
        if request.user.is_authenticated:
            context['username']= request.user.username
        return render(request, 'blog/category.html', context=context)
    

    修改模板文件

     模板文件中大部分和首页差不多

    <!-- templates/blog/category.html -->
    <!-- blog-content -->
    ...
        <div class="container content">
          <div class="blog-header">
            <h1 class="blog-title ">Simple</h1>
            <p class="lead blog-description">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Non quos commodi mollitia possimus, ab ad inventore consectetur in nam! Enim harum ipsum aspernatur similique et, quia earum dolor accusantium unde?</p>
          </div>
          <nav aria-label="breadcrumb">
            <ol class="breadcrumb bg-light">
              <li class="breadcrumb-item active" aria-current="page">{{ category }}</li>
              <!-- <li class="breadcrumb-item active" aria-current="page">Library</li> -->
            </ol>
          </nav>
    
          <div class="row">
            <div class="col-sm-8">
              {% if article_list %}
              {% for article in article_list %}
              <div class="card">
                  <img src="{% static 'blog/img/1.jpg' %}" alt="cat" class="card-img-top">
                  <div class="card-body">
                    <h5 class="card-title">{{ article.title }}</h5>
                    <p class="card-text">{{ article.abstract }}</p>
                    <a href="{% url 'blog:article' article.title %}" class="btn btn-dark">more</a>
                  </div>
              </div>
              {% endfor %}
              {% endif %}
            </div>
    ...
    

     以上部分是最大的不同点

    模板继承

     仔细对比,可以发现首页和分类页面有很大的相同,而这些相同地方的代码无疑是重复,django 中,将重复的 html 代码抽离出来形成一个新的 html 文件,之后通过特定的标签进行继承。

    分离代码

     将相同的代码抽离放在 templates/base.html

    <!-- templates/base.html -->
    {% load staticfiles %}
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
        <title>Fbckf Blog</title>
    
        <!-- Bootstrap -->
        <link href="{% static 'blog/css/bootstrap.min.css' %}" rel="stylesheet">
        <link href="{% static 'blog/css/base.css' %}" rel="stylesheet">
        <link rel="stylesheet" type="text/css" href="{% static 'blog/css/font-awesome.css' %}">
        <link rel="stylesheet" type="text/css" href="{% static 'blog/css/font-awesome.min.css' %}">
    
        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->
      </head>
      <body>
        <!-- nav -->
        <div class="container">
          <nav class="navbar navbar-light border-bottom" style="background-color: white">
            <span class="navbar-brand font-italic">
              <a href="{% url 'blog:index' %}" class="btn-light">
              Fbckf
              </a>
            </span>
            <div class="my-2 my-lg-0">
              {% if username %}
              <a href="/admin" class="btn btn-outline-dark" role="button">{{ username }}</a>
              {% else %}
              <a href="/admin" class="btn btn-outline-dark" role="button">Sign in</a>
              {% endif %}
            </div>        
          </nav>
        </div>
    
        <!-- blog-content -->
        <div class="container content">
          <div class="blog-header">
            <h1 class="blog-title ">Simple</h1>
            <p class="lead blog-description">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Non quos commodi mollitia possimus, ab ad inventore consectetur in nam! Enim harum ipsum aspernatur similique et, quia earum dolor accusantium unde?</p>
          </div>
    
        <!-- 用 block 标签将不同部分替代 -->
            {% block body %}
            {% endblock body %}
    
    
            <div class="col-sm-4 col-sm-offset blog-sidebar">
              <div class="sidebar-module sidebar-module-inset">
                <h4>关于</h4>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam alias fugiat, commodi eum fugit in fuga veritatis magni, velit minima tenetur deserunt minus repellat ea voluptatibus consequuntur asperiores quam cumque.</p>
              </div>
              <div class="sidebar-module">
                <h4>分类</h4>
                <ul class="list-group">
                {% for category in category_list %}
                  <li class="list-group-item d-flex justify-content-between align-items-center">
                    <a href="{% url 'blog:category' category.name %}">{{ category.name }}</a>
                    <span class="badge badge-light badge-pill">{{ category.article_count }}</span>
                  </li>
                {% empty %}
                  <li class="list-group-item d-flex justify-content-between align-items-center">
                    暂无分类
                  </li>
                {% endfor %}
                </ul>
              </div>
              <div class="sidebar-module">
                <div class="input-group mb-3 content">
                  <div class="input-group-prepend">
                    <span class="input-group-text" id="basic-addon1">
                      <i class="fa fa-search" aria-hidden="true"></i>
                    </span>
                  </div>
                  <form action="{% url 'blog:search' %}" method="post">
                    {% csrf_token %}
                  <input name="query" type="text" class="form-control" placeholder="Search" aria-label="Search" aria-describedby="basic-addon1">
                  </form>
                </div>
              </div>
            </div>
          </div>   
        </div>
    
        {% if is_page %}
        <!-- Pagination -->
        <div class="justify-content-center">
          <nav aria-label="Page navigation">
            <ul class="pagination justify-content-center">
              <li class="page-item">
                <a href="?page=1" class="page-link bg-light text-dark" aria-label="Previous">
                  <span aria-hidden="true">&laquo;</span>
                  <span class="sr-only">Previous</span>
                </a>
              </li>
            {% ifequal article_list.number article_list.paginator.num_pages %}
              <li class="page-item"><a href="?page={{ article_list.number|add:-2 }}" class="page-link bg-light text-dark">{{ article_list.number|add:-2 }}</a></li>
            {% endifequal %}
    
            {% ifnotequal article_list.number|add:-1 0 %}
              <li class="page-item"><a href="?page={{ article_list.number|add:-1 }}" class="page-link bg-light text-dark">{{ article_list.number|add:-1 }}</a></li>
            {% endifnotequal %}
    
              <li class="page-item disabled"><a href="?page={{ article_list.number }}" class="page-link bg-dark text-light">{{ article_list.number}}</a></li>
    
            {% ifnotequal article_list.number article_list.paginator.num_pages %}
              <li class="page-item"><a href="?page={{ article_list.number|add:1 }}" class="page-link bg-light text-dark">{{ article_list.number|add:1 }}</a></li>
            {% endifnotequal %}
    
            {% ifequal article_list.number|add:-1 0 %}
              <li class="page-item"><a href="?page={{ article_list.number|add:2 }}" class="page-link bg-light text-dark">{{ article_list.number|add:2 }}</a></li>
            {% endifequal %}
              <li class="page-item">
                <a href="?page={{ article_list.paginator.num_pages}}" class="page-link bg-light text-dark" aria-label="Next">
                  <span aria-hidden="true">&raquo;</span>
                  <span class="sr-only">Next</span>
                </a>
              </li>
            </ul>
          </nav>
        </div>
        {% endif %}
        
        <!-- button-back-top -->
        <button class="btn btn-outline-dark back-top" id="backTop">
          <i class="fa fa-arrow-up" aria-hidden="true"></i>
        </button>
    
        <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
        <script src="{% static 'blog/js/jquery-3.2.1.min.js' %}"></script>
        <!-- Include all compiled plugins (below), or include individual files as needed -->
        <script src="{% static 'blog/js/bootstrap.min.js' %}"></script>
        <!-- myjq -->
        <script src="{% static 'blog/js/base.js' %}"></script>
      </body>
    </html>
    

    &esmp;以上就是两个模板文件的相同部分,提取出来之后,修改 index.htmlcategory.html 模板,将相同部分删除,只留下不同部分

    <!-- templates/blog/index.html -->
    {% extends 'base.html' %}
    {% load staticfiles %}
    {% block body %}
          <div class="row">
            <div class="blog-main col-sm-8">
            {% for article in article_list %}
              <div class="jumbotron bg-light">
                <h1 class="display-4">{{ article.title }}</h1>
                <p class="lead">{{ article.abstract }}</p>
                <hr class="my-4">
                <p class="text-muted">{{ article.create_time }} , by  {{ article.author }}</p>
                <a href="{% url 'blog:article' article.title %}" class="btn btn-dark btn-lg" role="button">Read more</a> 
              </div>
            {% empty %}
             {% if error_msg %}
                <div class="jumbotron bg-light">
                  <p class="lead">{{ error_msg }}</p>
                </div>
              {% else %}      
                <div class="jumbotron bg-light">
                  <p class="lead">暂无文章,敬请期待!</p>
                </div>
              {% endif %}
            {% endfor %}
            </div> 
    {% endblock body %}
    

     通过 {% extends 'base.html' %} 继承 base.html 模板,再使用 {% block %} 标签将代码包括起来,渲染时会替代 base.html 模板中的相同标签。

    category.html 模板也差不多

    <!-- templates/blog/category.html -->
    {% extends 'base.html' %}
    {% load staticfiles %}
    
    {% block body %}
          <nav aria-label="breadcrumb">
            <ol class="breadcrumb bg-light">
              <li class="breadcrumb-item active" aria-current="page">{{ category }}</li>
              <!-- <li class="breadcrumb-item active" aria-current="page">Library</li> -->
            </ol>
          </nav>
    
          <div class="row">
            <div class="col-sm-8">
              {% if article_list %}
              {% for article in article_list %}
              <div class="card">
                  <img src="{% static 'blog/img/1.jpg' %}" alt="cat" class="card-img-top">
                  <div class="card-body">
                    <h5 class="card-title">{{ article.title }}</h5>
                    <p class="card-text">{{ article.abstract }}</p>
                    <a href="{% url 'blog:article' article.title %}" class="btn btn-dark">more</a>
                  </div>
              </div>
              {% endfor %}
              {% endif %}
            </div>
    {% endblock body %}
    

     分类页面也有分页功能,需要修改视图函数

    # blog/views.py
    ...
    def category(request, slug):
        context = {}
        if slug:
            category = Category.objects.get(name=slug)
            context['category'] = category.name
            article_list = category.article_set.all().order_by('-create_time')
            if article_list.count() > 10:
                paginator = Paginator(article_list, 5)
                page = request.GET.get('page')
                if page == None:
                    page=1
                page_list = paginator.page(page)
                context['article_list'] = page_list
                context['is_page'] = True
            else:
                context['article_list'] = article_list
            category_list = Category.objects.all()
            context['category_list'] = category_list
            if request.user.is_authenticated:
                context['username']= request.user.username
            return render(request, 'blog/category.html', context=context)
    

    总结

     总的来说,个人博客项目到这里就已经完成了,剩下的只是一些细微的调整。之后可以将项目部署到服务器上使用了。

    相关文章

      网友评论

          本文标题:Django笔记11-分类页面与模板继承

          本文链接:https://www.haomeiwen.com/subject/bgfmmftx.html