Django_01

第一节 跑通基本流程

第一个项目

一、首先,新建一个项目(project), 名称为 project_01

用命令行的方式:
  • 打开终端,进入在当前用户的某个目录下,使用命令:django-admin startproject [项目名称]即可创建一个项目。比如:

    django-admin startproject project_01
    

    备注:

    1. 如果 django-admin 不行,请用 django-admin.py
    2. 如果是在Linux是用源码安装的,或者用 pip 安装的,也是用 django-admin.py 命令
使用Pycharm的方式

pycharm新建一个Django项目,新建项目的截图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m7fcqqzX-1575720169973)(C:\Users\WINDOW 10\Desktop\笔记\Django\Image\image-20191207191434233.png)]
创建完项目后,会看到如下目录结构:
在这里插入图片描述

这些目录和文件的用处是:
  • 最外层的:file: project_01 根目录只是你项目的容器, Django 不关心它的名字,你可以将它重命名为任何你喜欢的名字。
  • manage.py: 一个让你用各种方式管理 Django 项目的命令行工具。
  • 里面一层的 project_01/ 目录包含你的项目,它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的Python 包名。 (比如 project_01.urls).
  • init.py:一个空文件,告诉Python 这个目录应该被认为是一个Python 包。
  • settings.py:Django项目的配置文件,具体请查看全局配置文件详解一节
  • urls.py:Django 项目的 URL 声明,就像你网站的“目录”。
  • wsgi.py:作为你的项目的运行在WSGI 兼容的Web服务器上的入口。
运行Django项目
  1. 通过命令行的方式,进入当前项目路径下(manage.py那个文件的目录),使用命令:python manage.py runserver。这样可以在本地访问你的网站,默认端口号是8000,这样就可以在浏览器中通过http://127.0.0.1:8000/来访问你的网站啦。

  2. 通过Pycharm运行。直接点击右上角的绿色箭头按钮即可运行。

  3. 使用Pycharm的终端,方式和命令行一样。
    在这里插入图片描述

    注:使用pyhon不成功时,改为python、python3或其它,具体的看自己的环境(python)是如何启动的。后面也是如此。

   你刚刚启动的是 Django 自带的用于开发的简易服务器,它是一个用纯 Python 写的轻量级的 Web 服务器。我们将这个服务器内置在 Django 中是为了让你能快速的开发出想要的东西,因为你不需要进行配置生产级别的服务器(比如 Apache)方面的工作,除非你已经准备好投入生产环境了。

提醒:千万不要 将这个服务器用于和生产环境相关的任何地方。这个服务器只是为了开发而设计的。(我们在 Web 框架方面是专家,在 Web 服务器方面并不是。)

  现在,服务器正在运行,浏览器访问 https://127.0.0.1:8000/。你将会看到一个“祝贺”页面,随着一只火箭发射,服务器已经运行了。
在这里插入图片描述

补充:如要显示中文,请将settings.py中的LANGUAGE_CODE = "en-us"改为LANGUAGE_CODE = "zh-hans" #设置为中文显示

更换端口

  默认情况下,runserver 命令会将服务器设置为监听本机内部 IP 的 8000 端口。如果你想更换服务器的监听端口,请使用命令行参数。举个例子,下面的命令会使服务器监听 8080 端口:

python manage.py runserver 8080

  如果你想要修改服务器监听的IP,在端口之前输入新的。比如,为了监听所有服务器的公开IP(这你运行 Vagrant 或想要向网络上的其它电脑展示你的成果时很有用),使用:

python manage.py runserver 0:8000

0 是 0.0.0.0 的简写,完整的写法为python manage.py runserver 0.0.0.0:8000

二、视图和 URL 分发器

  • 对于django的设计框架MVT,用户在URL中请求的是视图,视图接收请求后进行处理,并将处理的结果返回给请求者
  • 使用视图时需要进行两步操作
    • 1.定义视图函数(访问页面时的内容)
    • 2.定义视图函数相关的URL(网址) (即规定 访问什么网址对应什么内容)
视图:

  视图一般都写在views.py中。并且视图的第一个参数永远都是request(一个HttpRequest)对象。这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等。在视图中,一般是完成逻辑相关的操作。比如这个请求是添加一篇博客,那么可以通过request来接收到这些数据,然后存储到数据库中,最后再把执行的结果返回给浏览器。视图函数的返回结果必须是HttpResponseBase对象或者子类的对象。

在先前创建的project_01目录下的 project_01目录新建一个 view.py 文件,并输入代码:

from django.http import HttpResponse 
def hello(request): 
	return HttpResponse("Hello World ! ")

注:这里的字符串可以使用标签如

HttpResponse("<H1>Hello World ! </H1>")
URL映射:

  视图写完后,要与URL进行映射,也即用户在浏览器中输入什么url的时候可以请求到这个视图函数。在用户输入了某个url,请求到我们的网站的时候,django会从项目的urls.py文件中寻找对应的视图。在urls.py文件中有一个urlpatterns变量,以后django就会从这个变量中读取所有的匹配规则。匹配规则需要使用django.urls.path函数进行包裹,这个函数会根据传入的参数返回URLPattern或者是URLResolver的对象。

打开 urls.py 文件,添加以下代码:

from django.contrib import admin
from django.urls import path
from . import view
urlpatterns = [
    path('admin/', admin.site.urls)
    #url(r'^$', view.index),#1.x版本的写法,每个正则表达式前面的'r' 是可选的但是建议加上。
    path('', view.index),
]

Django2. 0中可以使用 re_path() 方法来兼容 1.x 版本中的 url() 方法,一些正则表达式的规则也可以通过 re_path() 来实现 。
完成后,启动 Django 开发服务器,并在浏览器访问打开浏览器并访问:127.1.1.1:8000
在这里插入图片描述

注意: 项目中如果代码有改动,服务器会自动监测代码的改动并自动重新载入,所以如果你已经启动了服务器则不需手动重启。

带变量的URL

  日常开发过程中,有时一个URL可以代表多个不同的页面,如编写带有日期的URL,根据前面编写方式,按照一年计算,需要开发者编写365个不同的URL才能实现,这种做法显然不可取,因此Django在编写URL时,需要对URL设置变量,使URL具有多样性。
URL的变量类型有字符类型、整型、slug和uuid,最为常见的是字符型和整型。

  • 字符类型:匹配任何非空字符串,不含斜杠。没有指定类型时,默认该类型
  • 整型: 匹配0和正整数
  • slug: 可以理解为注释、后缀或附属等概念
  • uuid: 匹配一个uuid格式的对象 UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准

实例:网页做加减法的实现

  1. 采用 /add/?name1=value&name2=value2这样GET方法进行
    在项目的view.py中添加如下代码“
    from django.http import HttpResponse
    def add(request):
        a = request.GET['a']
        b = request.GET['b']
        c = int(a)+int(b)
        return HttpResponse(str(c))
    
    注:request.GET 类似于一个字典,更好的办法是用 request.GET.get('a', 0) 当没有传递 a 的时候默认 a 为 0
  2. 添加一条URL:
    from django.contrib import admin
    from django.urls import path
    from . import view
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', view.index),
        path('add/', view.add),
        #url(r'^add/$', 'view.add'),1.x的版本
    ]
    

  我们打开开发服务器并访问:http://127.0.0.1:8002/add/?a=99&b=5,就可以看到网页上显示一个 104,试着改变一下a和b对应的值试试看?在这里插入图片描述
如果没有添加add/?a=9&b=5就会看到错误信息:MultiValueDictKeyError at /add/
在这里插入图片描述
2. 采用 /add/value1/value2/ 这样的网址的方式
我们接着修改 view.py文件,再新定义一个add2 函数,原有部分不再贴出

def add2(request, a, b):
    c = int(a) + int(b)
    return HttpResponse(str(c))

接着修改urls.py 文件,再添加一个新的 url:

path('add/<int:a>/<int:b>/', view.add2),

在Django的1.x版本中下写法有所不同:

url(r'^add/(\d+)/(\d+)/$', 'view.add2'),#1.x版本,使用re_path可以兼容这种方式

  我们可以看到网址中多了 (\d+), 正则表达式中 \d 代表一个数字,+ 代表一个或多个前面的字符,写在一起 \d+ 就是一个或多个数字,用括号括起来的意思是保存为一个子组(更多知识请参见 Python 正则表达式),每一个子组将作为一个参数,被 view.py 中的对应视图函数接收。
注意:1.x传入的参数类型是字符串类型,这与2.x的版本有所不同
我们再访问http://127.0.0.1:8002/add/99/5/就可以看到和刚才同样的效果,但是这回网址更优雅了

三、创建App

  经过前面的练习,我们可能已经发现,我们所有的路由规则都写在项目下的urls.py中,如果我们的项目路由规则很多的话,urls.py会变得冗杂,并且不利于调试,views.py也会有同样的问题。为了避免这个问题,我们可以在每个Django项目中可以包含多个APP,每个APP拥有自己的views.py和urls.py,相当于一个大型项目中的分系统、子模块、功能部件等等,相互之间比较独立,但也可以有联系。所有的APP共享项目资源。应用(APP)可以存放在任何Python path中定义的路径,这里我们放在项目下的路径即可。

项目 VS 应用

  appdjango项目的组成部分。一个app代表项目中的一个模块,所有URL请求的响应都是由app来处理。比如豆瓣,里面有图书,电影,音乐,同城等许许多多的模块,如果站在django的角度来看,图书,电影这些模块就是app,图书,电影这些app共同组成豆瓣这个项目。因此这里要有一个概念,django项目由许多app组成,一个app可以被用到其他项目,django也能拥有不同的app

在终端,cd进入项目路径下(即有manage.py的目录),输入

python manage.py startapp 应用名

这里建立的是Longin:

python manage.py startapp Login

注:如使用的是IDE开发,如PyCharm,可以使用工具自带的终端,如
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R2FU2qHl-1575720169976)(C:\Users\WINDOW 10\Desktop\笔记\Django\Image)]
这样就创建了一个叫做login的APP,django自动生成“login”文件夹,及一系列文件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TiCChAA1-1575720169976)(C:\Users\WINDOW 10\Desktop\笔记\Django\Image)]

  应用创建好了,我们需要在项目目录下的project_01文件夹下的settings.py配置文件里的INSTALLED_APPS选项里注册应用。申明Login这个文件夹是一个APP应用。

注册用两种方法:

  • 在INSTALLD_APPS 列表后面加上:‘应用名’:

  • 在INSTALLD_APPS 列表后面加上:‘应用名.apps.App01Config’(推荐使用这种写法)

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'Login'#这是我们的应用,名称为Login
    'app01.apps.App01Config'#这是我们的应用,名称为app01
]

这样我们的第一个应用程序创建完毕。

在Login/views.py中编写和前面类似视图函数,如

from django.http import HttpResponse
def index(request):
    return HttpResponse("<H1>这是Login应用.</H1>")

  如果想看见效果,我们还需要将一个 URL 映射到它——这就是我们需要 URLconf 的原因了。

​  在我们的项目中,不可能只有一个app,如果把所有的appviews中的视图都放在urls.py中进行映射,肯定会让代码显得非常乱。因此django给我们提供了一个方法,可以在app内部包含自己的url匹配规则,而在项目的urls.py中再统一包含这个appurls。使用这个技术需要借助include函数。

为了创建 URLconf,请在Login目录里新建一个urls.py文件。

from django.urls import path
from Login import views
urlpatterns = [
    path('index', views.index),
]

  下一步是要在根 URLconf 文件中指定我们创建的 Login.urls 模块。在 project_01/urls.py 文件的 urlpatterns 列表里插入一个 include(), 如下:

from django.contrib import admin
from django.urls import path, include
from . import view
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', view.index),
    path('Login/', include('Login.urls')),
]

  函数 include() 允许引用其它 URLconfs。每当 Django 遇到include() 时,它会截断与此项匹配的 URL 的部分,并将剩余的字符串发送到 URLconf 以供进一步处理。

**注:**Django2. 0以后可以使用 re_path() 方法来兼容 1.x 版本中的 url() 方法,一些正则表达式的规则也可以通过 re_path() 来实现

  这样,在项目(project_01)urls.py文件中就把所有的和Login这个app相关的url都移动到Login/urls.py中了,然后在project_01/urls.py中,通过include函数包含Login.urls,以后在请求Login相关的url的时候都需要加一个Login的前缀。

以后访问indexurl的时候,就通过/Login/index/来访问。
在这里插入图片描述
  在前面的学习中,我们只是在页面显示了简单的字符串,在数据库查出的数据并没有显示在页面上,但是,实际开发中,我们需要将数据显示在页面上,这就需要模板了。

四、模板的基本使用:

在前面的学习中,我们只是在页面显示了简单的字符串,但是,我们的需求并不止如此······

  • 如何向请求者返回一个漂亮的页面呢?肯定需要用到html、css,如果想要更炫的效果还要加入js,问题来了,这么一堆字段串全都写到视图中,作为HttpResponse()的参数吗?这样定义就太麻烦了吧,因为定义字符串是不会出任何效果和错误的,如果有一个专门定义前端页面的地方就好了

  • 解决问题的技术来了:模板

  • 在Django中,将前端的内容定义在模板中,然后再把模板交给视图调用,各种漂亮、炫酷的效果就出现了

创建模板:
  • 创建模板文件夹,两种方法:

    • 在项目根下创建templates目录,然后把模板存入在templates目录里,多个APP的话,就直接在templates目录下建立与APP名相同名称的目录即可。Django会自动查找到,这种方法简单、直观,适合个人或小项目。

    • 各个APP下单独建立一个templates目录,然后再建立一个与项目名相同的的目录,把模板放到对应的目录里。这样的方法适合大项目多人协作,每个人只负责各自的APP项目的时候。多样式多站点(域名)的情况也适用,不同的APP用不同的模板样式,不同的域名。

      两种方法各有优点,大家选适合自己的就好。

  • 使用模板前,先设置TEMPLATES里的’DIRS’为’DIRS’: [os.path.join(BASE_DIR, ‘templates’)],添加模板目录templates的路径,这样Django才能自动找到模板页面:

    #修改前
    'DIRS': []
    #修改后
    'DIRS': [os.path.join(BASE_DIR, 'templates')]
    
  • 创建完成后,将文件夹templates标记为模板文件夹,在文件夹右键

在这里插入图片描述

注:如果使用IDE,IDE可能已经为我们提前做好了上面的工作,我们直接使用即可,

  现在,我们就可所以在templates文件夹下编写模板文件了,在这之前,让我们先来了解一下最基本的模板语法。

模板语法

  概述:在Django框架中,模板是可以帮助开发者快速生成呈现给用户页面的工具,模板的设计方式实现了MVT中VT的解耦,VT有着N:M的关系,一个V可以调用任意T,一个T可以供任意V使用

  • 模板处理分为两个过程
    • 加载
    • 渲染

模板的实质就是一个是HTML页面,可以根据视图中传递过来的数据进行填充。模板主要有两个部分:
  ① HTML静态代码
  ② 动态插入的代码段(挖坑,填坑)
模板中的动态代码段除了做基本的静态填充,还可以实现一些基本的运算,转换和逻辑。

变量
  • 视图传递给模板的数据

  • 遵守标识符规则

  • 变量使用了双括号如:

    {{ var }}
    

    var可以是输出值,可以是变量,也可以是对象,属性

  • 如果变量不存在,则插入空字符串
点语法
  • 字典查询

  • 属性或者方法

  • 索引

模板中的小弊端,调用对象的方法,不能传递参数

标签

语法:

 {% tag %}
  • 作用

    1. 加载外部传入的变量
    2. 在输出中创建文本
    3. 控制循环或逻辑
    if/else标签:
        {% if condition %}
         ... display
        {% endif %}
    

    或者:

        {% if condition1 %}
        ... display 1
        {% elif condiiton2 %}
        ... display 2
        {% else %}
        ... display 3
        {% endif %}
    

    根据条件判断是否输出。if/else 支持嵌套。

    {% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not ),例如:

    {% if athlete_list and coach_list %}
         athletes 和 coaches 变量都是可用的。
    {% endif %}
    
    for 标签

    {% for %}允许我们在一个序列上迭代。

      与Python的 for 语句的情形类似,循环语法是for X in Y,Y是要迭代的序列而X是在每一个特定的循环中使用的变量名称。
      每一次循环中,模板系统会渲染在{% for %}{% endfor %}之间的所有内容。

        {% for 变量 in 列表 %}
        	语句1
        {% empty %}
        	语句2
        {% endfor %}
    

      当列表为空或不存在时,执行empty之后的语句,不使用{% empty %},列表为空或不存在时,不执行任何语句。可以嵌套使用{% for %} 标签:

注释标签

Django 单行注释使用 {# #}

{# 这是一个注释 #}

Django多行注释

    {% comment %}
    	注释内容
    {% endcomment %}	
模板的使用

现在可以正式开始使用模板了

在templates/Login下新建一个HTML文件,用于输出用户列表。

userlist.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户列表</title>
</head>
<body>
<table border="1px" cellspacing="0px">
    <caption><h3>用户列表</h3></caption>
    <tr>
        <td>用户名</td>
        <td>性别</td>
        <td>邮箱</td>
    </tr>
    {% for user in  userlist %}
        <tr>
            <td>{{ user.0 }}</td>
            <td>{{ user.1 }}</td>
            <td>{{ user.2 }}</td>
        </tr>
    {% endfor %}
</table>
</body>
</html>
  • 调用模板分为三步骤
    • 1.找到模板
    • 2.定义上下文
    • 3.渲染模板

打开Login/views.py新建视图函数:

from django.http import HttpResponse
from django.template import loader,RequestContext
import random
def userlist(request):
    # 定义列表保存用户信息
    list = []
    for i in range(10):
        s = random.randint(0, 1000)
        list.append(['Jack%d%d' % (i, s), random.choice(['男', '女', '保密']), '%d%d@163.com' % (i, s * s)])
    # 1.获取模板
    template = loader.get_template('Login/userlist.html')
    # 2.定义上下文
    context = {'userlist': list}
    # 3.渲染模板
    return HttpResponse(template.render(context))  # 其实就是讲模板渲染成了字符串
视图调用模板简写
  • 视图调用模板都要执行以上三部分,于是Django提供了一个函数render封装了以上代码;在实际开发中也多用render方法。

  • 方法render包含3个参数

    • 第一个参数为request对象
    • 第二个参数为模板文件路径
    • 第三个参数为字典,表示向模板中传递的上下文数据
    from django.shortcuts import render
    import random
    def userlist(request):
        # 定义字典,用来保存要发送到页面的数据
        content = {}
        # 定义列表保存用户信息
        list = []
        for i in range(10):
            s = random.randint(0, 1000)
            list.append(['Jack%d%d' % (i, s), random.choice(['男', '女', '保密']), '%d%d@163.com' % (i, s * s)])
        content['userlist'] = list
        return render(request, 'Login/userlist.html', content)
    

添加对应的URL:

    path('userlist/', views.userlist),

记住:每次写完path后都在后面添加一个“,”。
上面两种写法任选其一,这里我们使用后面一直写法,启动服务器访问http://127.0.0.1:8000/Login/userlist/,可看到以下结果:
在这里插入图片描述

URL跳转

我们每次跳转网页的时候,都在浏览器的地址栏输入url,这样太麻烦了,有没有解决的办法呢?请看下面的例子:
在templates文件夹下添加文件index.html

<!DOCTYPE html>
<html>
<head>
    <title>跳转</title>
</head>
<body>
<a href="/add/4/5/">计算 4+5</a>
<a href="/Login/userlist.html">用户列表</a>
</body>
</html>

在根路由(project_01的view.py中)中添加:

    path('index/', view.index2),

项目的(不是Login应用)view.py中添加

def index2(request):
    return render(request, 'index.html')

重启服务器访问http://127.0.0.1:8000/index/看到如下界面:
在这里插入图片描述
点击相应的链接,就会跳转到相应的页面:
在这里插入图片描述
在这里插入图片描述
有没有更好的方法呢?当然有,我们会在后面讲到。

五、模型

1、定义模型类

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

  Django通过自定义Python类的形式来定义具体的模型,每个模型的物理存在方式就是一个Python的类Class,每个模型代表数据库中的一张表,每个类的实例代表数据表中的一行数据,类中的每个变量代表数据表中的一列字段。Django通过模型,将Python代码和数据库操作结合起来,实现对SQL查询语言的封装。也就是说,你可以不会管理数据库,可以不会SQL语言,你同样能通过Python的代码进行数据库的操作。Django通过ORM对数据库进行操作,奉行代码优先的理念,将Python程序员和数据库管理员进行分工解耦。
  Django规定,如果要使用模型,必须要创建一个app。这里我们已经创建了一个Login应用,直接在login下定义模型即可:

在Login的models文件添加如下代码:

from django.db import models
class User(models.Model):
    '''用户表'''
    gender = (
        ('male', '男'),
        ('female', '女'),
    )
    name = models.CharField(max_length=128, unique=True)
    password = models.CharField(max_length=256)
    email = models.EmailField(unique=True)
    sex = models.CharField(max_length=32, choices=gender, default='男')
    c_time = models.DateTimeField(auto_now_add=True)

以上的类名代表了数据库表名,且继承了models.Model,类中各字段含义如下:

  • name必填,最长不超过128个字符,并且唯一,也就是不能有相同姓名;
  • password必填,最长不超过256个字符(实际可能不需要这么长);
  • email使用Django内置的邮箱类型,并且唯一;
  • 性别使用了一个choice,只能选择男或者女,默认为男;
  • 使用__str__帮助人性化显示对象信息;
  • 元数据里定义用户按创建时间的反序排列,也就是最近的最先显示;

备注:上面的内容这里只需要知到什么意思即可,不必深究,后面会详细的去学习。

2、查看数据库

​ 首先在终端执行python manage.py migrate
在这里插入图片描述
这样,运行服务器的时候以下警告信息就消失了,后面提到的的db.sqlite3文件也会出现在项目下

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them.

  • 在settings.py中关于数据库的默认配置如下:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    • 表示采用sqlite3数据库,并将文件放在项目目录下
    • 从下次课开始使用mysql数据库,会讲解如何配置mysql数据库
    • 运行过服务器后,会生成数据库文件,如下图:
  • 可以在pycharm中查看数据库,按下图打开database面板
    在这里插入图片描述

  • 在database面板中按下图打开选择数据库窗口
    在这里插入图片描述
  • 选择数据库窗口如下图,找到项目目录下的db.sqlite3文件:
    在这里插入图片描述
  • 如果未安装驱动,点击安装驱动即可
    注:在Pycharm双击项目下的db.sqlite3也可以完成上述操作
    在这里插入图片描述
  • 打开数据库后窗口如下图:
    在这里插入图片描述
3、启用模型
  • f分两步完成:
    • 1.生成迁移文件:根据模型类生成创建表的语句
    • 2.执行迁移:根据第一步生成的语句在数据库中创建表
  • 打开Terminal窗口,编写如下命令:
python manage.py makemigrations

在这里插入图片描述
通过运行makemigrations命令,Django 会检测你对模型文件的修改,也就是告诉Django你对模型有改动,并且你想把这些改动保存为一个“迁移(migration)”。
migrations是Django保存模型修改记录的文件,这些文件保存在磁盘上。在例子中,它就是Login/migrations/0001_initial.py,你可以打开它看看,里面保存的都是人类可读并且可编辑的内容,方便你随时手动修改。

  • 执行迁移命令如下:
python manage.py migrate

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Rjwfip4-1575720169981)(C:\Users\WINDOW 10\Desktop\笔记\Django\Image\image-20191206233418481.png)]

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

​ migrations的功能非常强大,允许你随时修改你的模型,而不需要删除或者新建你的数据库或数据表,在不丢失数据的同时,实时动态更新数据库。我们将在后面的章节对此进行深入的阐述,但是现在,只需要记住修改模型时的操作分三步
​ ​ 1. 在models.py中修改模型;
​ ​ 2. 运行python manage.py makemigrations为改动创建迁移记录;
​ ​ 3. 运行python manage.py migrate,将操作同步到数据库。

​ 之所以要将创建和实施迁移的动作分成两个命令两步走是因为你也许要通过版本控制系统(例如github,svn)提交你的项目代码,如果没有一个中间过程的保存文件(migrations),那么github如何知道以及记录、同步、实施你所进行过的模型修改动作呢?毕竟,github不和数据库直接打交道,也没法和你本地的数据库通信。但是分开之后,你只需要将你的migration文件(例如上面的0001)上传到github,它就会知道一切。

  • 其它数据表是django已经定义好的功能,可以直接使用

  • 在database面板中刷新后如下图,对应的表被创建成功:
    在这里插入图片描述

4、数据库的操作
增加

​ 与传统SQL相比,django的一个较大的优势是定义了一个统一的方法save(),用于完成模型的Insert和Update操作,在执行模型实例的save()函数时,django会根据模型的主键,判断记录是否存在,如果存在则执行Update操作,否则执行Delete操作

语法:对象名.save()

def AddUsers(request):
    for i in range(10):
        s = random.randint(0, 1000)
        user = Users(name='tom%d%d' % (i, s), password='123456', email='%d%d@qq.com' % (i, s * s), sex=random.choice(['男', '女', '保密']))
        user.save()
    return HttpResponse("<p>保存成功</p>")

对应的URL:

path('AddUser/', views.AddUsers),

运行后,数据库users表增加10条数据。
在这里插入图片描述

查找
查询函数
  • 类名.objects.方法名(查询条件)

    • get:返回表中满足条件的一条数据,是模型类的实例对象,若查询到多条数据则抛出MultipleObjectsReturned,若查不到数据则抛出DoesNotExist;
    • all:返回表中的所有数据,是QuerySet类型的实例对象,其是由多个实例对象组成的查询集,支持迭代;
    • filter:返回满足条件的数据,同上,参数中写查询条件;
    • exclude:返回不满足条件的数据,同上,同上;
    • order_by:对查询结果进行排序,同上,参数中写根据排序的字段;
    • exists:判断查询集中是否有数据,有则返回True,无则返回False;
      此上方法都针对查询集,即可以通过查询集.filter()等方法得到新的查询集或一个模型类的实例对象,当取出了单条数据如get后则为模型类的实例。
  • 实例:

    建立如下视图函数:

    def QueryUser(request):
        # 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
        userlist = {}
        users = Users.objects.all()
        userlist['userlist'] = users
        return render(request, 'Login/userlist.html', context=userlist)
    

    编写对应的HTML模板文件:、

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户列表</title>
    </head>
    <body>
    <table border="1px" cellspacing="0px">
        <caption><h3>用户列表</h3></caption>
        <tr>
            <td>用户名</td>
            <td>性别</td>
            <td>邮箱</td>
            <td>注册时间</td>
        </tr>
        {% for user in  userlist %}
            <tr>
                <td>{{ user.name }}</td>
                <td>{{ user.sex }}</td>
                <td>{{ user.email }}</td>
                <td>{{ user.c_time }}</td>
            </tr>
        {% endfor %}
    </table>
    </body>
    </html>
    

    添加URL

    path('QueryUser/', views.QueryUser),
    

    启动服务器,会将数据库查到的数据展示在页面:
    在这里插入图片描述

修改

修改可以调用增加的方式,也可以使用update方法

def UpdateUser(request):
    # 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATE
    user = Users.objects.get(id=1)
    user.name = 'Google'
    user.save()
    # 另外一种方式
    Users.objects.filter(id=2).update(name='Google2')
    list = Users.objects.all()
    dict = {'userlist': list}
    return render(request, 'Login/userlist.html', context=dict)

update可以修改多个字段如:

User.objects.get(name='Aaron').update(name='Rose', sex='nv')

对应的URL:

path('UpdateUser/', views.UpdateUser),

运行后可以发现数据库的数据已经更新:
在这里插入图片描述
在这里插入图片描述

删除

django模型提供了delete()方法用于删除记录,既可以删除单条记录也可以删除数据集

def DelUser(request):
    Users.objects.all().delete() #删除所有用户
    return HttpResponse("删除成功!")

对应的URL:

path('DelUser/', views.DelUser),

运行后数据库的users表中所有数据都会被删除!

有关模型的更多知识,会在后面详细去阐述

​ 现在,我们已将初步了解了Django开发的流程,其中一些方法,会在后面详细的去讲解,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
[ERROR][2023-06-08 13:17:01,837][log.py:230]Internal Server Error: /admin/material_scrap/materialscraphead/69/change/ Traceback (most recent call last): File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\core\handlers\exception.py", line 47, in inner response = get_response(request) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\contrib\admin\options.py", line 616, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\utils\decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\views\decorators\cache.py", line 44, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\contrib\admin\sites.py", line 232, in inner return view(request, *args, **kwargs) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\contrib\admin\options.py", line 1660, in change_view return self.changeform_view(request, object_id, form_url, extra_context) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\utils\decorators.py", line 43, in _wrapper return bound_method(*args, **kwargs) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\utils\decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\contrib\admin\options.py", line 1540, in changeform_view return self._changeform_view(request, object_id, form_url, extra_context) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\contrib\admin\options.py", line 1586, in _changeform_view self.save_model(request, new_object, form, not add) File "C:\work\django_app\dj_erp\apps\material_scrap\admin.py", line 138, in save_model reason = request.POST['materialscrapdetail_set-0-reason'] File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\db\models\base.py", line 485, in __init__ _setattr(self, field.name, rel_obj) File "C:\Users\suzisxue\Anaconda3\envs\django_dev\lib\site-packages\django\db\models\fields\related_descriptors.py", line 220, in __set__ self.field.remote_field.model._meta.object_name, ValueError: Cannot assign "<class 'material_scrap.models.MaterialScrapHead'>": "MaterialScrapDetail.serialNum" must be a "MaterialScrapHead" instance.
06-09

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值