victory的博客

长安一片月,万户捣衣声

0%

Django | django通用视图

  • 使用django通用视图简化代码

使用django开发网站的常见情况是根据 URL 中的参数从数据库中获取数据、载入模板文件然后返回渲染后的模板。 由于这种情况特别常见,Django 提供一种快捷方式,叫做 通用视图系统。

1.修改[app_name]/urls.py中的URLconf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.urls import path

from . import views

app_name = "[app_name]"
urlpatterns = [
path("", views.IndexView.as_view(), name="index"),
# ex: /[app_name]/1/
path("<int:pk>/", views.DetailView.as_view(), name="detail"),
# ex: /[app_name]/1/results/
path("<int:pk>/results/", views.ResultsView.as_view(), name="results"),
# ex: /[app_name]/1/vote/
path("<int:question_id>/vote/", views.vote, name="vote"),
]

2.使用通用视图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from django.db.models import F
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic

from .models import Choice, Question


class IndexView(generic.ListView):
template_name = "[app_name]/index.html"
context_object_name = "latest_question_list"

def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.order_by("-pub_date")[:5]


class DetailView(generic.DetailView):
model = Question
template_name = "[app_name]/detail.html"


class ResultsView(generic.DetailView):
model = Question
template_name = "[app_name]/results.html"

3.模型类(帮助理解URLconf和view)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import datetime

from django.db import models
from django.utils import timezone

# Create your models here.
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField("date published")

def __str__(self):
return self.question_text

def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)


class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)

def __str__(self):
return self.choice_text

4.模板(帮助理解URLconf和view)

模板1:index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
</body>
</html>

模板2:detail.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ question.question_text }}</h1>
<ul>
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<fieldset>
<legend><h1>{{ question.question_text }}</h1></legend>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
</fieldset>
<input type="submit" value="Vote">
</form>
</ul>
</body>
</html>

模板3:results.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_test }} -- {{choice.votes}} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
</body>
</html>