Hellodjango article 06: blog from “streaking” to “skinny”

Time:2020-5-22

The sample code involved in this article has been synchronously updated to the hellogithub team warehouse

Before that, we have written the homepage view of the blog, and configured the URL and template so that Django can correctly handle HTTP requests and return appropriate HTTP responses. But we just returned a sentence on the front page: “welcome to my blog”, which is a view function at hello world level, without any beauty.

In this article, we need to write a real homepage view function. When users visit our blog homepage, they will see the list of blog articles we published, as shown in the demonstration project.

Home view function

In the previous section, we explained the development process of Django. First, configure the URL, bind the URL to the corresponding view function, and write it in the urls.py In the documents, and then in the engineering urls.py File import. The second is to write the view function. In the view, we need to render the template settings.py The template related configuration is carried out in, so that Django can find the template to be rendered. Finally, return the rendered HTTP response. The related configuration and preparation work are completed before, here we just need to concentrate on writing the view function, so that it can achieve the function we want.

The view function of the home page is actually very simple. The code is like this:

blog/views.py

from django.shortcuts import render
from .models import Post

def index(request):
    post_list = Post.objects.all().order_by('-created_time')
    return render(request, 'blog/index.html', context={'post_list': post_list})

We talked about model manager in the previous sectionobjectsUse of. Here we useall()Method to get all the articles from the databasepost_listVariable.allMethod returns aQuerySet(it can be understood as a data structure similar to a list). Since the list of blog articles is usually arranged in reverse order according to the publication time, i.e. the latest articles are at the top, we callorder_byMethod to sort the returned queryset. Sort bycreated_time, which is the creation time of the article.-Sign indicates reverse order, if not added-Is a positive order. And then, as we’ve done before, we render blogindex.html The template file contains thepost_listVariable passed to template.

Working with static files

Our project uses a set of blog templates downloaded from the Internet (click here to download the full template). In addition to HTML documents, there are also some CSS files and JavaScript files to make the web page present the style we see now. We also need to make some necessary configuration for Django, so that Django can know how to introduce these CSS and JavaScript files into the development server, so as to make the CSS style of blog page effective.

By convention, we put CSS and JavaScript files in theBlog ApplicationUnder the static directory of. So, firstBlog ApplicationCreate a static folder under. At the same time, in order to avoid naming conflicts with CSS and JavaScript files in other applications (other applications may also have CSS and JavaScript files with the same name as blog applications), we will create a blog folder in the static directory, and copy the CSS and JS files in the downloaded blog template together with all the files in the directory. Finally, our blog application directory structure should be as follows:

blog\
    __init__.py
    static\
        blog\
            css\
                . CSS file
            js\
                . JS file
    admin.py
    apps.py
    migrations\
        __init__.py
    models.py
    tests.py
    views.py

Use the index.html We wrote it ourselves before the file was replaced index.html Documents. If you are curious, you can run the development server now to see what the home page looks like.

Hellodjango article 06: blog from

As shown in the figure, you can see that the style displayed on the front page is very confusing, because the browser cannot load CSS and other style files correctly. We need Django to handle the loading path of static files such as CSS and JavaScript correctly. CSS style files are usually introduced in the head tags of HTML documents, and opened index.html File, find the contents of the head label package at the beginning of the file, like this:

templates/blog/index.html

<!DOCTYPE html>
<html>
  <head>
      <title>Black &amp; White</title>

      <!-- meta -->
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">

      <!-- css -->
      <link rel="stylesheet" href="css/bootstrap.min.css">
      <link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
      <link rel="stylesheet" href="css/pace.css">
      <link rel="stylesheet" href="css/custom.css">

      <!-- js -->
      <script></script>
      <script></script>
      <script></script>
      <script></script>
  </head>
  <body>
      <! -- other contents -- >
      <script></script>
  </body>
</html>

The path of CSS style file is in the link tag’s href attribute, while the path of JavaScript file is in the script tag’s SRC attribute. You can see things like ` href = “CSS/ bootstrap.min.css “Or such a reference, because the path of the referenced files is not correct, the browser failed to import these files. We need to change them to the right path. Change the code to the following, and correctly import the CSS and JavaScript files under the static file:

templates/blog/index.html

+ {% load static %}
<!DOCTYPE html>
<html>
  <head>
      <title>Black &amp; White</title>

      <!-- meta -->
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">

      <!-- css -->
      - <link rel="stylesheet" href="css/bootstrap.min.css">
      <link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
      - <link rel="stylesheet" href="css/pace.css">
      - <link rel="stylesheet" href="css/custom.css">
      + <link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
      + <link rel="stylesheet" href="{% static 'blog/css/pace.css' %}">
      + <link rel="stylesheet" href="{% static 'blog/css/custom.css' %}">

      <!-- js -->
      - <script></script>
      - <script></script>
      - <script></script>
      - <script></script>
      + <script></script>
      + <script></script>
      + <script></script>
      + <script></script>
  </head>
  <body>
      <! -- other contents -- >
      - <script></script>
      + <script></script>
  </body>
</html>

Here – means delete this line, and + means add this line. (see carefully what has been added, and don’t miss it.)

We put the reference path in a strange symbol, such as: href = “{% static ‘blog / CSS/ bootstrap.min.css ‘ %}”。 Wrapped in {%%} is called a template label. As we said earlier, the variables wrapped in {} are called template variables, which are used to display the variable values passed from the view function in the final rendered template. The function of the template label we use here is similar to the function, such asstaticTemplate tag, which takes the following string'css/bootstrap.min.css'Convert to the correct file entry path. In this way, the CSS and JS files can be loaded correctly and the style can be displayed normally.

be careful:

In order to use the {% static%} template label in the template, don’t forget to use {% load static%} at the top. The static template tag is located in the static module. The {% static%} tag can only be used in the template after the module is introduced through the load template tag.

After the replacement, you can refresh the page and look at the source code of the page to see what value the {% static%} template label is replaced with after the page is rendered. For example, we can see

<link rel="stylesheet" href="{% static 'blog/css/pace.css' %}">

This section finally displays in the browser:

<link rel="stylesheet" href="/static/blog/css/pace.css">

This is exactly pace.css The path of the file. Other file paths are similarly replaced. You can see that the function of the {% static%} tag is to prefix the following string with / static /{% static 'blog/css/pace.css' %}The final rendered value is/static/blog/css/pace.css。 And the / static / prefix is that we settings.py Passed in fileSTATIC_URL = '/static/'designated. In fact, if we write the reference path directly as/static/blog/css/pace.cssYes, so why use the {% static%} tag? Think about it. At present, the prefix of URL is / static /. If one day, for some reasons, we need to change / static / to / resource /. If you write a direct reference to Lujin without using the static template tag, you may need to change n places. If you use the static template tag, you can settings.py Just change one place, i.eSTATIC_URL = '/static/'Change toSTATIC_URL = '/resource/'

Tips

Sometimes the page is still messy after pressing F5, which may be because the browser has cached the previous results. Press Shift + F5 (some browsers may be Ctrl + F5) to force the browser page to refresh. If not, restart the development server and clear the browser cache.

Note the introduction of a CSS file here

<link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">

We did not use the template label, because the file referred here is an external file, not a file under the staticblogcss directory in our project, so we do not need to use the template label.

After the static file is introduced correctly, the style display is normal.

Hellodjango article 06: blog from

Modify template

At present, we only see some pre populated data in the template, and we have to let it display the article data obtained from the database. Here is a little bit of template modification:

In template index.html You will find a series of article tags in:

templates/blog/index.html

...
<article class="post post-1">
  ...
</article>

<article class="post post-2">
  ...
</article>

<article class="post post-3">
  ...
</article>
...

The contents of the package here show the article data. We passed a template in the view function indexpost_listVariable, which contains the article list data taken from the database. Just like python, we can loop the list in the template, loop out articles one by one, and then display the data of articles one by one. To use loops in a template, you need to use the previously mentioned template tag, this time using the {% for%} template tag. Will index.html Delete the redundant article labels in, leave only one article label, and write the following code:

templates/blog/index.html

...
{% for post in post_list %}
  <article class="post post-{{ post.pk }}">
    ...
  </article>
{% empty %}
  < div class = "no post" > articles that haven't been published yet! </div>
{% endfor %}
...

You can see that the syntax is similar to Python’s for loop, just wrapped in a template label symbol like {%%}. The function of {% empty%} is whenpost_listEmpty, that is, when there is no article in the database, the following contents will be displayed. Finally, we use {% endfor%} to tell Django that the loop ends here.

You may not understand thepostandpost_listWhat is it?post_listIt’s aQuerySet(similar to the data structure of a list), each of which is previously defined in the blogmodels.py Each instance corresponds to the record of each article in the database. So we loop through itpost_list, the results of each traversal are saved inpostVariable. So we use template variables to displaypostProperty value of. Like here{{ post.pk }}(PK is the abbreviation of primary key, that is, post corresponds to the ID value recorded in the database. Although we do not display the definition, Django will automatically add it for us.).

Now we can pass through the circulatory systempostVariable to access the data of a single article. Analyze the HTML content in the article tag. H1 shows the title of the article,

<h1 class="entry-title">
    <a href="single.html">Adaptive Vs. Responsive Layouts And Optimal Text Readability</a>
</h1>

Let’s replace the title withpostOftitleProperty value. Note that you wrap it in the template variable, because it will eventually be replaced with the actual title value.

<h1 class="entry-title">
    <a href="single.html">{{ post.title }}</a>
</h1>

The following five span tags show the category, article release time, article author, number of comments and reading volume respectively.

<div class="entry-meta">
  < span class = "post category" ></a></span>
  <span class="post-date"><a href="#"><time class="entry-date"
                                            Datetime = "2012-11-09t23:15:57 + 00:00" > May 11, 2017 < / time ></a></span>
  < span class = "post author" ></a></span>
  < span class = "comments link" ></a></span>
  < span class = "views count" ></a></span>
</div>

Replace some data again. Because the number of comments and the amount of reading can’t be replaced for the time being, we will keep it first. We will modify it after realizing these functions. At present, we only replace the classification, article release time and article author:

<div class="entry-meta">
  <span class="post-category"><a href="#">{{ post.category.name }}</a></span>
  <span class="post-date"><a href="#"><time class="entry-date"
                                            datetime="{{ post.created_time }}">{{ post.created_time }}</time></a></span>
  <span class="post-author"><a href="#">{{ post.author }}</a></span>
  < span class = "comments link" ></a></span>
  < span class = "views count" ></a></span>
</div>

Here’s the summary in the P tag

<div class="entry-content clearfix">
  <p>Free, Chinese, zero base, complete project, based on the latest Django 1.10 and python 3.5. Take you step by step to develop your own blog site from scratch, and help you master Django as fast as possible
    Developing techniques</p>
  <div class="read-more cl-effect-14">
    Read on to < span class = "meta NAV" > → < / span ></a>
  </div>
</div>

replace withpostSummary of:

<div class="entry-content clearfix">
  <p>{{ post.excerpt }}</p>
  <div class="read-more cl-effect-14">
    Read on to < span class = "meta NAV" > → < / span ></a>
  </div>
</div>

Visit the home page again, it shows: articles that have not been published yet! OK, so much work has been done, but there is no data in the database! Next, we will actually write several articles and save them in the database to see how the display effect is.