There’s usually more than one type of blog post: sometimes you’ll write incomprehensible technical posts, and sometimes you’ll just write about the mood of the day.
Therefore, the classification of articles is quite important, which is convenient for bloggers to classify and archive articles, and also convenient for users to have targeted reading.
An important way to classify articles is to set up columns.
Column model
There are many ways to realize the function of article column. You can simply add the CharField() field to the article’s Model and store the column name as a string (in reality, this implementation is more like ** “tags” **, more on that later). This has the advantage of being simpler; The disadvantages are obvious: you may get confused with column names over time, and it is not convenient to expand other attributes of the column.
Therefore, the column of the article can be an independent Model, with foreign keys associated with the Model of the article.
Modify article/modles.py:
article/models.py
...
class ArticleColumn(models.Model):
""" The Model of the column ""
# Column title
title = models.CharField(max_length=100, blank=True)
# create time
created = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
class ArticlePost(models.Model):.# "one to many" foreign key in the article column
column = models.ForeignKey(
ArticleColumn,
null=True,
blank=True,
on_delete=models.CASCADE,
related_name='article')...Copy the code
The column’s Model has two fields, Name and Creation date.
An article has only one column, and a column can correspond to multiple articles, so a one-to-many relationship is established.
After writing the model, use Hoisting and Migrate commands to migrate data.
Displays columns in the list
Adding test Data
Once the model is written, several columns of data are needed to test it. Since you haven’t written a view yet, you need to make good use of Django’s built-in backend.
First register the column model in the background:
article/admin.py
...
from .models import ArticleColumn
# Sign up for the articles column
admin.site.register(ArticleColumn)
Copy the code
Then you can add the column’s data entry in the background:
I added HTML, Java, and Django at random.
Open a random article in the background, and the column field is waiting for you quietly:
Randomly select several articles and set different columns for testing.
Rewrite article list
Earlier we used a card-type UI to present the list of articles.
The advantage of cards is that they are simple and elegant, but as the amount of data increases, the small size of the cards becomes overwhelmed.
So here’s rewriting the list loop for the list.html template:
article/list.html
...
<! -- List loop -->
<div class="row mt-2">
{% for article in articles %}
<! -->
<div class="col-12">
<! - section - >
{% if article.column %}
<button type="button"
class="btn btn-sm mb-2 {% if article.column.title == 'Django' %} btn-success {% elif article.column.title == 'Java' %} btn-danger {% elif article.column.title == 'HTML' %} btn-warning {% endif %} "
>
{{ article.column }}
</button>
{% endif %}
<! - the title -- -- >
<h4>
<b>
<a href="{% url 'article:article_detail' article.id %}"
style="color: black;"
>
{{ article.title }}
</a>
</b>
</h4>
<! -- -- -- > the
<div>
<p style="color: gray;">
{{ article.body|slice:'100' }}...
</p>
</div>
<! - the footnote - >
<p>
<! -- Additional information -->
<span style="color: green;">{{article. Total_views}} browse </span>
<span style="color: blue;">{{article. Created | date: 'Y -m - d'}} release & have spent </span>
<span style="color: darkred;">{{article. Updated | date: 'Y -m - d'}} update</span>
</p>
<hr>
</div>
{% endfor %}
</div>.Copy the code
The main change is the addition of a “column” button. We even have different button colors for different columns.
In the additional information, the date information that was not used before has also been added.
Take a look at the results:
It feels good!
Modify the write article function
Presentation is fine, but you can’t select columns when publishing new articles.
Modify the template for writing an article by adding the following content to the form:
templates/article/create.html
...
<! -- Form for submitting articles -->
<form method="post" action=".">
{% csrf_token %}
<! -- Article title -->.<! -- Article column -->
<div class="form-group">
<label for="column">The column</label>
<select class="form-control"
id="column"
name="column"
>
<option value="none">Please select column..</option>
{% for column in columns %}
<option value="{{ column.id }}">{{ column }}</option>
{% endfor %}
</select>
</div>
<! -- Text -->.<! -- Submit button -->.</form>
Copy the code
< SELECT > is the drop-down selection component of the form. In this component, loop through all the column data and set the value property to specify the ID value of the form submission column.
Refresh the page like this:
As before, you can show it, but you don’t have the view logic to process the form.
Modify the existing write article view article_create() to handle column data for form uploads:
article/views.py
# Introduce column Model
from .models import ArticleColumn
...
# View for writing articles.def article_create(request):
if request.method == "POST":...if article_post_form.is_valid():
...
# New code
if request.POST['column'] != 'none':
new_article.column = ArticleColumn.objects.get(id=request.POST['column'])
# Existing code
new_article.save()
...
else:...# New and modified code
columns = ArticleColumn.objects.all()
context = { 'article_post_form': article_post_form, 'columns': columns }
...
Copy the code
The new code involves two parts: GET and POST:
- POST: The main consideration is that some articles can be columns free. So with
if
Statement determines whether the article has a column, and if so, submits according to the formvalue
Value, associated with the corresponding column. - GET: Adds context to columns for use by templates.
To test this, the column function for writing articles should work properly.
Modify update view
The view for updating articles also needs to be updated.
Change the template first:
templates/article/update.html
...
<! -- Form for submitting articles -->
<form method="post" action=".">
{% csrf_token %}
<! -- Article title -->.<! -- Article column -->
<div class="form-group">
<label for="column">The column</label>
<select class="form-control"
id="column"
name="column"
>
<option value="none">Please select column..</option>
{% for column in columns %}
<option value="{{ column.id }}"
{% if column.id= =article.column.id %}
selected
{% endif %}
>
{{ column }}
</option>
{% endfor %}
</select>
</div>
<! -- Text -->.<! -- Submit button -->.</form>.Copy the code
In a slightly different way, the form determines whether column.id is equal to article.column.id, and if so, sets it to the default.
Then modify the view function:
article/views.py
# Update the post.def article_update(request, id):.Determine whether the user submits form data for POST
if request.method == "POST":...if article_post_form.is_valid():
...
# New code
if request.POST['column'] != 'none':
article.column = ArticleColumn.objects.get(id=request.POST['column'])
else:
article.column = None.else:...# New and modified code
columns = ArticleColumn.objects.all()
context = {
'article': article,
'article_post_form': article_post_form,
'columns': columns,
}
...
Copy the code
The code logic is similar. Modify the column function of the article, also completed.
conclusion
This chapter has realized the simple column function, can comfortably classify the article, the Gospel of obsessive-compulsive disorder.
There are also some things that can be improved, such as:
-
Click the Columns button to display all articles in the same column. This function is very similar to the sort of the hottest articles and search articles you’ve learned before. Remember the filter() method?
-
Add, delete, change and check column Model.
For individual blogs, column data changes are usually minimal. If you don’t want to add, delete, modify, and check, it is perfectly possible to modify data in the background.
I will not repeat the above. It is left to the reader to try to implement.
- If you have any questions please leave a message on Doucet’s personal website and I will reply as soon as possible.
- Or Email me a private message: [email protected]
- Project code: Django_blog_tutorial