码迷,mamicode.com
首页 > 其他好文 > 详细

django项目mysite

时间:2019-08-21 00:30:12      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:转发   style   png   val   引擎   开始   into   文件中   change   

项目建立

建立项目mysite

技术图片

各文件和目录解释:

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

 启动开发服务器

技术图片

 

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

$ python manage.py runserver

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

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

技术图片

创建投票应用(app)

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

app应用与project项目的区别:

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

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

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

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: Whats up?>]>

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

# 获取今年发布的问卷
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: Whats 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: Whats 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: Whats 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>

 

django项目mysite

标签:转发   style   png   val   引擎   开始   into   文件中   change   

原文地址:https://www.cnblogs.com/xiao-apple36/p/11299700.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!