创建项目
Django 命令
(learnDjango) ~\> django-admin
Type 'django-admin help <subcommand>' for help on a specific subcommand.
Available subcommands:
[django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
runserver
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver
Note that only Django core commands are listed as settings are not properly configured (error: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE
or call settings.configure() before accessing settings.).
创建一个项目并尝试运行
django-admin startproject demo
cd demo
python manage.py runserver
创建管理员用户
python manage.py migrate
python .\manage.py createsuperuser
运行项目
# http://127.0.0.1:8000/
python manage.py runserver
# http://127.0.0.1:8080/
python manage.py runserver 8080
# http://ip:8000/ 可以从外部访问
python manage.py runserver 0:8000
Hello world!
创建应用
python manage.py startapp helloworld
编辑 settings.py
,添加如下代码
INSTALLED_APPS = [
'helloworld.apps.HelloworldConfig',
]
编辑 helloworld/templates/helloworld/index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Hello world!</title>
</head>
<body>
<h1>{{ text }}</h1>
</body>
</html>
编辑 helloworld/views.py
from django.shortcuts import render
def index(request):
return render(request, 'helloworld/index.html', {'text': "Hello world!"})
编辑 helloworld/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
编辑 urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('helloworld/', include('helloworld.urls')),
]
编写一个投票应用
创建应用
python manage.py startapp polls
编辑 settings.py
,添加如下代码
INSTALLED_APPS = [
'polls.apps.PollsConfig',
]
定义模型
编辑 polls/models.py
,定义模型并创建表结构
from django.db import models
# 话题
class Topic(models.Model):
topic_text = models.CharField(max_length=200)
topic_date = models.DateTimeField('date published')
# 返回对象描述信息
def __str__(self):
return self.topic_text
# 投票选项
class Choice(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
choice_count = models.IntegerField(default=0)
# 返回对象描述信息
def __str__(self):
return self.choice_text
# 让 Django 知道模型变更
python manage.py makemigrations polls
# 创建表结构
python manage.py migrate polls
编辑模板
编辑 index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>polls</title>
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}">
</head>
<body>
{#显示话题列表#}
{% if latest_topic_list %}
<ul>
{% for topic in latest_topic_list %}
<li><a href="{% url 'polls:detail' topic.id %}">{{ topic.topic_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>话题列表为空!</p>
{% endif %}
</body>
</html>
编辑 detail.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>detail</title>
</head>
<body>
{#话题内容#}
<p>{{ topic.topic_text }}</p>
{#错误信息#}
{% if error_message %} <p><strong>{{ error_message }}</strong></p> {% endif %}
{#表单部分#}
<form action="{% url 'polls:vote' topic.id %}" method="post">
{% csrf_token %}
{% for choice in topic.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 %}
<br>
<input type="submit" value="Vote">
</form>
</body>
</html>
编辑 result.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>results</title>
</head>
<body>
{#话题内容#}
<p>{{ topic.topic_text }}</p>
{#投票结果#}
<table border="1">
{% for choice in topic.choice_set.all %}
<tr>
<td>{{ choice.choice_text }}</td>
<td>{{ choice.choice_count }}</td>
</tr>
{% endfor %}
</table>
<br>
{#再次投票#}
<a href="{% url 'polls:detail' topic.id %}">再次投票</a>
</body>
</html>
编辑视图
编辑 polls/views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
from django.utils import timezone
from .models import Topic, Choice
# 主页视图
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_topic_list'
def get_queryset(self):
return Topic.objects.filter(
topic_date__lte=timezone.now()
).order_by('-topic_date')[:5]
# 话题详情页视图
class DetailView(generic.DetailView):
model = Topic
template_name = 'polls/detail.html'
# 投票结果视图
class ResultsView(generic.DetailView):
model = Topic
template_name = 'polls/result.html'
# 投票
def vote(request, topic_id):
topic = get_object_or_404(Topic, pk=topic_id)
try:
choice_selected = topic.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'topic': topic,
'error_message': "你没有选择一个选项!",
})
else:
choice_selected.choice_count += 1
choice_selected.save()
# 重定向到 result 页面
return HttpResponseRedirect(reverse('polls:result', args=(topic.id,)))
编辑路由
编辑路由 polls/urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
# ex: /polls/
path('', views.IndexView.as_view(), name='index'),
# ex: /polls/5/
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
# ex: /polls/5/results/
path('<int:pk>/result/', views.ResultsView.as_view(), name='result'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
编辑全局路由 urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
]