django项目mysite

项目创建

创建项目mysitehtml

各文件和目录解释:python

  • 外层的mysite/目录与Django无关,只是你项目的容器,能够任意重命名。
  • manage.py:一个命令行工具,用于与Django进行不一样方式的交互脚本,很是重要!
  • 内层的mysite/目录是真正的项目文件包裹目录,它的名字是你引用内部文件的包名,例如:mysite.urls
  • mysite/__init__.py:一个定义包的空文件。
  • mysite/settings.py:项目的主配置文件,很是重要!
  • mysite/urls.py:路由文件,全部的任务都是从这里开始分配,至关于Django驱动站点的内容表格,很是重要!
  • mysite/wsgi.py:一个基于WSGI的web服务器进入点,提供底层的网络通讯功能,一般不用关心。

 启动开发服务器mysql

 

或进入mystie项目的根目录,输入下面的命令:程序员

$ python manage.py runserver

Django提供了一个用于开发的web服务器,使你无需配置一个相似Ngnix的生产服务器,就能让站点运行起来。这是一个由Python编写的轻量级服务器,简易而且不安全,所以不要将它用于生产环境。web

打开浏览器,访问http://127.0.0.1:8000/,你将看到Django的火箭欢迎界面,一切OK!正则表达式

建立投票应用(app)

在 Django 中,每个应用(app)都是一个 Python 包,而且遵循着相同的约定。Django 自带一个工具,能够帮你生成应用的基础目录结构。sql

app应用与project项目的区别:shell

  • 一个app实现某个功能,好比博客、公共档案数据库或者简单的投票系统;
  • 一个project是配置文件和多个app的集合,这些app组合成整个站点;
  • 一个project能够包含多个app;
  • 一个app能够属于多个project!

一般app将它们放在与manage.py脚本同级的目录下,这样方便导入文件。数据库

进入mysite项目根目录,确保与manage.py文件处于同一级,输入下述命令django

python manage.py startapp polls

  系统会自动生成 polls应用的目录,其结构以下

在Pycharm中,没有能够建立app的图形化按钮,须要在下方的Terminal终端中输入命令

编写视图

polls/views.py文件中,编写代码

from django.http import HttpResponse


def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")

为了调用该视图,咱们还须要编写urlconf,也就是路由。如今,在polls目录中新建一个文件,名字为urls.py,在其中输入代码以下:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

接下来,在项目的主urls.py文件中添加urlpattern条目,指向咱们刚才创建的polls这个app独有的urls文件,

这里须要导入include模块。打开mysite/urls.py文件,代码以下

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]

include语法至关于多级路由,它把接收到的url地址去除与此项匹配的部分,将剩下的字符串传递给下一级路由

include的背后是一种即插即用的思想。项目根路由不关心具体app的路由策略,只管往指定的二级路由转发,实现了应用解耦。

app所属的二级路由能够根据本身的须要随意编写,不会和其它的app路由发生冲突。app目录能够放置在任何位置,而不用修改路由。这是软件设计里很常见的一种模式。

好了,路由设置成功后,启动服务器,而后在浏览器中访问地址http://localhost:8000/polls/。一切正常的话,你将看到“Hello, world. You’re at the polls index.”

path()方法

路由系统中最重要的path()方法能够接收4个参数,其中2个是必须的:routeview,以及2个可选的参数:kwargsname

route:

route 是一个匹配 URL 的准则(相似正则表达式)。当 Django 响应一个请求时,它会从 urlpatterns 的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项,

而后执行该条目映射的视图函数或下级路由,其后的条目将再也不继续匹配。所以,url路由的编写顺序很是重要!

须要注意的是,route不会匹配 GET 和 POST 参数或域名。例如,URLconf 在处理请求 https://www.example.com/myapp/时,

它会尝试匹配 myapp/。处理请求 https://www.example.com/myapp/?page=3 时,也只会尝试匹配 myapp/

view:

view指的是处理当前url请求的视图函数。当Django匹配到某个路由条目时,自动将封装的HttpRequest对象做为第一个参数,被“捕获”的参数以关键字参数的形式,传递给该条目指定的视图view。

kwargs:

任意数量的关键字参数能够做为一个字典传递给目标视图。

name:

对你的URL进行命名,让你可以在Django的任意处,尤为是模板内显式地引用它。这是一个很是强大的功能,至关于给URL取了个全局变量名,不会将url匹配地址写死

 

数据库配置

打开mysite/settings.py配置文件,这是整个Django项目的设置中心。Django默认使用SQLite数据库,

由于Python源生支持SQLite数据库,因此你无须安装任何程序,就能够直接使用它。固然,若是你是在建立一个实际的项目,可使用相似PostgreSQL的数据库

# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

若是你想使用其余的数据库,请先安装相应的数据库操做模块,并将settings文件中DATABASES位置的’default’的键值进行相应的修改,用于链接你的数据库。其中:

  • ENGINE(引擎):能够是django.db.backends.sqlite3django.db.backends.postgresqldjango.db.backends.mysqldjango.db.backends.oracle,固然其它的也行。

  • NAME(名称):相似Mysql数据库管理系统中用于保存项目内容的数据库的名字。若是你使用的是默认的SQLite,那么数据库将做为一个文件将存放在你的本地机器内,

           此时的NAME应该是这个文件的完整绝对路径包括文件名,默认值os.path.join(BASE_DIR, ’db.sqlite3’),将把该文件储存在你的项目目录下。

基于pymysql操做Mysql数据库的例子

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

import pymysql         # 必定要添加这两行!经过pip install pymysql!
pymysql.install_as_MySQLdb()


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'cnblog',
        'USER': 'root',
        'PASSWORD': '111',
        'HOST': '127.0.0.1',
        'PORT': 3306
      
    }
}


# mysql orm转换sql日志
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

 

注意:

  • 在使用非SQLite的数据库时,请务必预先在数据库管理系统的提示符交互模式下建立数据库,你可使用命令:CREATE DATABASE database_name;。Django不会自动帮你作这一步工做。
  • 确保你在settings文件中提供的数据库用户具备建立数据库表的权限,由于在接下来的教程中,咱们须要自动建立一个test数据表。(在实际项目中也须要确认这一条要求。)
  • 若是你使用的是SQLite,那么你无需作任何预先配置,直接使用就能够了。

在修改settings文件时,请顺便将TIME_ZONE设置为国内所在的时区Asia/Shanghai

同时,请注意settings文件中顶部的INSTALLED_APPS设置项。它列出了全部的项目中被激活的Django应用(app)。你必须将你自定义的app注册在这里。每一个应用能够被多个项目使用,而且能够打包和分发给其余人在他们的项目中使用。

默认状况,INSTALLED_APPS中会自动包含下列条目,它们都是Django自动生成的:

  • django.contrib.admin:admin管理后台站点
  • django.contrib.auth:身份认证系统
  • django.contrib.contenttypes:内容类型框架
  • django.contrib.sessions:会话框架
  • django.contrib.messages:消息框架
  • django.contrib.staticfiles:静态文件管理框架

上面的一些应用也须要创建一些数据库表,因此在使用它们以前咱们要在数据库中建立这些表。使用下面的命令建立数据表:

python manage.py migrate

  

建立模型

如今,咱们来定义模型model,模型本质上就是数据库表的布局,再附加一些元数据。

Django经过自定义Python类的形式来定义具体的模型,每一个模型的物理存在方式就是一个Python的类Class,每一个模型表明数据库中的一张表,每一个类的实例表明数据表中的一行数据,类中的每一个变量表明数据表中的一列字段。

Django经过模型,将Python代码和数据库操做结合起来,实现对SQL查询语言的封装。也就是说,你能够不会管理数据库,能够不会SQL语言,你一样能经过Python的代码进行数据库的操做。

Django经过ORM对数据库进行操做,奉行代码优先的理念,将Python程序员和数据库管理员进行分工解耦。

在这个简单的投票应用中,咱们将建立两个模型:QuestionChoice。Question包含一个问题和一个发布日期。Choice包含两个字段:该选项的文本描述和该选项的投票数。

每一条Choice都关联到一个Question。这些都是由Python的类来体现,编写的全是Python的代码,不接触任何SQL语句。如今,编辑polls/models.py文件

from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


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

 

上面的代码很是简单明了。每个类都是django.db.models.Model的子类。每个字段都是Field类的一个实例,例如用于保存字符数据的CharField和用于保存时间类型的DateTimeField,它们告诉Django每个字段保存的数据类型。

每个Field实例的名字就是字段的名字(如: question_text 或者 pub_date )。在你的Python代码中会使用这个值,你的数据库也会将这个值做为表的列名。

一些Field类必须提供某些特定的参数。例如CharField须要你指定max_length。这不只是数据库结构的须要,一样也用于数据验证功能。

有必填参数,固然就会有可选参数,好比在votes里咱们将其默认值设为0.

最后请注意,咱们使用ForeignKey定义了一个外键关系。它告诉Django,每个Choice关联到一个对应的Question(注意要将外键写在‘多’的一方)。Django支持通用的数据关系:一对一,多对一和多对多。

启用模型

上面的代码看着有点少,其实包含了大量的信息,据此,Django会作下面两件事:

  • 建立该app对应的数据库表结构
  • 为Question和Choice对象建立基于Python的数据库访问API

可是,首先咱们得先告诉Django项目,咱们要使用投票app。

要将应用添加到项目中,须要在INSTALLED_APPS设置中增长指向该应用的配置文件的连接。对于本例的投票应用,它的配置类文件PollsConfig是polls/apps.py

因此它的点式路径为polls.apps.PollsConfig。咱们须要在INSTALLED_APPS中,将该路径添加进去,实际上,在多数状况下,咱们简写成‘polls’就能够了:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls'
]

如今Django已经知道你的投票应用的存在了,并把它加入了项目你们庭。

咱们须要再运行下一个命令:

 python manage.py makemigrations polls

  

经过运行makemigrations命令,Django 会检测你对模型文件的修改,也就是告诉Django你对模型有改动,而且你想把这些改动保存为一个“迁移(migration)”。

migrations是Django保存模型修改记录的文件,这些文件保存在磁盘上。在例子中,它就是polls/migrations/0001_initial.py,你能够打开它看看,里面保存的都是人类可读而且可编辑的内容,方便你随时手动修改。

接下来有一个叫作migrate的命令将对数据库执行真正的迁移动做。可是在此以前,让咱们先看看在migration的时候实际执行的SQL语句是什么。有一个叫作sqlmigrate的命令能够展现SQL语句

python manage.py sqlmigrate polls 0001

  

请注意:

  • 实际的输出内容将取决于您使用的数据库会有所不一样。上面的是mySQL的输出。
  • 表名是自动生成的,经过组合应用名 (polls) 和小写的模型名questionchoice 。 ( 你能够重写此行为。)
  • 主键 (IDs) 是自动添加的。( 你也能够重写此行为。)
  • 按照惯例,Django 会在外键字段名上附加 "_id" 。 (你仍然能够重写此行为。)
  • 生成SQL语句时针对你所使用的数据库,会为你自动处理特定于数据库的字段,例如 auto_increment (MySQL), serial (PostgreSQL), 或integer primary key (SQLite) 。 在引用字段名时也是如此 – 好比使用双引号或单引号。
  • 这些SQL命令并无在你的数据库中实际运行,它只是在屏幕上显示出来,以便让你了解Django真正执行的是什么。

若是你感兴趣,也能够运行python manage.py check命令,它将检查项目中的错误,并不实际进行迁移或者连接数据库的操做。

$ python manage.py migrate

  

migrate命令对全部还未实施的迁移记录进行操做,本质上就是将你对模型的修改体现到数据库中具体的表上面。Django经过一张叫作django_migrations的表,记录并跟踪已经实施的migrate动做,经过对比得到哪些migrations还没有提交。

migrations的功能很是强大,容许你随时修改你的模型,而不须要删除或者新建你的数据库或数据表,在不丢失数据的同时,实时动态更新数据库。咱们将在后面的章节对此进行深刻的阐述,可是如今,只须要记住修改模型时的操做分三步:

  • 在models.py中修改模型;
  • 运行python manage.py makemigrations为改动建立迁移记录;
  • 运行python manage.py migrate,将操做同步到数据库。
mysql> show tables;
+----------------------------+
| Tables_in_poll             |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
| polls_choice               |
| polls_question             |
+----------------------------+
12 rows in set (0.00 sec)

 

使用模型的API

下面,让咱们进入Python交互环境,尝试使用Django提供的数据库访问API。要进入Python的shell,请输入命令

 python manage.py shell

  

相比较直接输入“python”命令的方式进入Python环境,调用manage.py参数能将DJANGO_SETTINGS_MODULE环境变量导入,

它将自动按照mysite/settings.py中的设置,配置好你的python shell环境,这样,你就能够导入和调用任何你项目内的模块了。

先进入一个纯净的python shell环境,而后启动Django。

当你进入shell后,尝试一下下面的API吧:

>>> from polls.models import Question, Choice # 导入咱们写的模型类
    # 如今系统内尚未questions对象
    >>> Question.objects.all()
    <QuerySet []>

    # 建立一个新的question对象
    # Django推荐使用timezone.now()代替python内置的datetime.datetime.now()
    # 这个timezone就来自于Django的依赖库pytz
    from django.utils import timezone
    >>> q = Question(question_text="What's new?", pub_date=timezone.now())

    # 你必须显式的调用save()方法,才能将对象保存到数据库内
    >>> q.save()

    # 默认状况,你会自动得到一个自增的名为id的主键
    >>> q.id
    1

    # 经过python的属性调用方式,访问模型字段的值
    >>> q.question_text
    "What's new?"
    >>> q.pub_date
    datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

    # 经过修改属性来修改字段的值,而后显式的调用save方法进行保存。
    >>> q.question_text = "What's up?"
    >>> q.save()

    # objects.all() 用于查询数据库内的全部questions
    >>> Question.objects.all()
    <QuerySet [<Question: Question object>]>

 

上面的<Question: Question object>是一个不可读的内容展现,你没法从中得到任何直观的信息,为此咱们须要一点小技巧,让Django在打印对象时显示一些咱们指定的信息。

返回polls/models.py文件,修改一下question和Choice这两个类,代码以下:

from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

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

这个技巧不但对你打印对象时颇有帮助,在你使用Django的admin站点时也一样有帮助。

从新启动一个新的python shell,再来看看其余的AP

>>> from polls.models import Question, Choice

# 先看看__str__()的效果,直观多了吧?
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django提供了大量的关键字参数查询API
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# 获取今年发布的问卷
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# 查询一个不存在的ID,会弹出异常
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.

# Django为主键查询提供了一个缩写:pk。下面的语句和Question.objects.get(id=1)效果同样.
>>> Question.objects.get(pk=1)
<Question: What's up?>

# 看看咱们自定义的方法用起来怎么样
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# 让咱们试试主键查询
>>> q = Question.objects.get(pk=1)

# 显示全部与q对象有关系的choice集合,目前是空的,尚未任何关联对象。
>>> q.choice_set.all()
<QuerySet []>

# 建立3个choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

# Choice对象可经过API访问和他们关联的Question对象
>>> c.question
<Question: What's up?>

# 一样的,Question对象也可经过API访问关联的Choice对象
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3

# API会自动进行连表操做,经过双下划线分割关系对象。连表操做能够无限多级,一层一层的链接。
# 下面是查询全部的Choices,它所对应的Question的发布日期是今年。(重用了上面的current_year结果)
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# 使用delete方法删除对象
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

 

admin后台管理站点

Django为你提供了一个基于项目model建立的一个后台管理站点admin。

这个界面只给站点管理员使用,并不对大众开放。虽然admin的界面可能不是那么美观,功能不是那么强大,内容不必定符合你的要求,

可是它是免费的、现成的,而且仍是可定制的,有完善的帮助文档。

1. 建立管理员用户

首先,咱们须要经过下面的命令,建立一个能够登陆admin站点的用户:

$ python manage.py createsuperuser
Email address: qianyi@123.com
Password:
Password (again):
The password is too similar to the email address.
Bypass password validation and create user anyway? [y/N]: n
Password:
Password (again):
(0.000) INSERT INTO `auth_user` (`password`, `last_login`, `is_superuser`, `username`, `first_name`, `last_name`, `email`, `is_staff`, `is_active`, `date_joined`) VALUES ('pbkdf2_sha256$120000$hxqaIpS92d
rd$eAOzMV+PAlgAmpWe32pUCCbnor4W1qw/Y7ygVwxdsrg=', NULL, 1, 'qianyi', '', '', 'qianyi@123.com', 1, 1, '2019-08-06 14:39:18.192940'); args=['pbkdf2_sha256$120000$hxqaIpS92drd$eAOzMV+PAlgAmpWe32pUCCbnor4W1q
w/Y7ygVwxdsrg=', None, True, 'qianyi', '', '', 'qianyi@123.com', True, True, '2019-08-06 14:39:18.192940']
Superuser created successfully.

 

2. 启动开发服务器

服务器启动后,在浏览器访问http://127.0.0.1:8000/admin/。你就能看到admin的登录界面了:

3.进入admin站点

利用刚才创建的帐户,登录admin,你将看到以下的界面:

 

当前只有两个可编辑的内容:groups和users。它们是django.contrib.auth模块提供的身份认证框架。

4. 在admin中注册投票应用

如今还没法看到投票应用,必须先在admin中进行注册,告诉admin站点,请将polls的模型加入站点内,接受站点的管理。

打开polls/admin.py文件,加入下面的内容:

from django.contrib import admin
from polls import models admin.site.register(models.Question) admin.site.register(models.Choice) # Register your models here.

点击“Questions”,进入questions的修改列表页面。这个页面会显示全部的数据库内的questions对象,你能够在这里对它们进行修改。

看到下面的What's new?了么?它就是咱们先前建立的一个question对象,而且经过__str__方法的帮助

这里须要注意的是:

  • 页面中的表单是由Question模型自动生成的。
  • 不一样的模型字段类型(DateTimeField, CharField)会表现为不一样的HTML input框类型。
  • 每个DateTimeField都会自动生成一个可点击连接。日期是Today,并有一个日历弹出框;时间是Now,并有一个通用的时间输入列表框。

 

在页面的底部,则是一些可选项按钮:

  • delete:弹出一个删除确认页面
  • save and add another:保存当前修改,并加载一个新的空白的当前类型对象的表单。
  • save and continue editing:保存当前修改,并从新加载该对象的编辑页面。
  • save:保存修改,返回当前对象类型的列表页面。

在页面的右上角,点击History按钮,你会看到你对当前对象的全部修改操做都在这里有记录,包括修改时间和操做人员,以下图所示:

视图和模板

一个视图就是一个页面,一般提供特定的功能,使用特定的模板。

编写视图

打开polls/views.py文件,输入下列代码:

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    # render()函数的第一个位置参数是请求对象(就是view函数的第一个参数),第二个位置参数是模板。还能够有一个可选的第三参数,
    # 一个字典,包含须要传递给模板的数据。最后render函数返回一个通过字典数据渲染过的模板封装而成的HttpResponse对象。
    return render(request, 'polls/index.html', context)

def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

polls/urls.py文件中加入下面的url模式,将其映射到咱们上面新增的视图

urlpatterns = [
    path('', views.index, name='index'),
# ex: /polls/5/
    path('<int:question_id>/', views.detail, name='detail'),
    # ex: /polls/5/results/
    path('<int:question_id>/results/', views.results, name='results'),
    # ex: /polls/5/vote/
    path('<int:question_id>/vote/', views.vote, name='vote'),
]

快捷方式:get_object_or_404()

get_object_or_404()方法将一个Django模型做为第一个位置参数,后面能够跟上任意个数的关键字参数,若是对象不存在则弹出Http404错误。

一样,还有一个get_list_or_404()方法,和上面的get_object_or_404()相似,只不过是用来替代filter()函数,当查询列表为空时弹出404错误。

(filter是模型API中用来过滤查询结果的函数,它的结果是一个列表集。而get则是查询一个结果的方法,和filter是一个和多个的区别!)

编写模板

polls/templates/polls/index.html:

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

 

 polls/detail.html

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

 

删除模板中硬编码的URLs

polls/index.html文件中,还有一部分硬编码存在,也就是href里的“/polls/”部分:

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

设想若是你在urls.py文件里修改了路由表达式,那么你全部的模板中对这个url的引用都须要修改,这是没法接受的!

使用前面给urls定义了一个name别名,能够用它来解决这个问题。具体代码以下

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

Django会在polls.urls文件中查找name='detail'的url,具体的就是下面这行:

path('<int:question_id>/', views.detail, name='detail'),

  举个栗子,若是你想将polls的detail视图的URL更换为polls/specifics/12/,那么你不须要在模板中从新修改url地址了,

仅仅只须要在polls/urls.py文件中,将对应的正则表达式改为下面这样的就好了,全部模板中对它的引用都会自动修改为新的连接:

# 添加新的单词'specifics'
path('specifics/<int:question_id>/', views.detail, name='detail'),

  

URL names的命名空间

本教程例子中,只有一个app也就是polls,可是在现实中很显然会有5个、10个、更多的app同时存在一个项目中。Django是如何区分这些app之间的URL name呢?

答案是使用URLconf的命名空间。在polls/urls.py文件的开头部分,添加一个app_name的变量来指定该应用的命名空间:

from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.index, name='index'),
# ex: /polls/5/
    path('<int:question_id>/', views.detail, name='detail'),
    # ex: /polls/5/results/
    path('<int:question_id>/results/', views.results, name='results'),
    # ex: /polls/5/vote/
    path('<int:question_id>/vote/', views.vote, name='vote'),
]

如今,让咱们将代码修改得更严谨一点,将polls/templates/polls/index.html中的

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

 修改成

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
相关文章
相关标签/搜索