Django

初识Django

环境 : Linux 7.4  Django 1.11+  Python 3.6

请求
用户 > 匹配url > urls.py路由 > 解析到视图 > views ,核心逻辑处理

 

 

通过视图views.py

  1. 通过QuerySet ---> modles --> DB数据库 ----> 返回数据给视图

  2. 通过模板进行渲染 --> template --> 返回HTML(JONS)页面 ---》 返到用户

  3. 通过views.py 直接返回给用户

MVC和MTV模式

Django的MTV模式本质是各组件之间为了保持松耦合关系,Django的MTV分别代表:

  1. Model(模型):负责业务对象与数据库的对象(ORM)

  2. Template(模版):负责如何把页面展示给用户

  3. View(视图):负责业务逻辑,并在适当的时候调用Model和Template

此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

locals() 返回给templates 渲染给 html 给用户

locals() #简写 ----》 {'data':data,'msg':msg} #正常写法

urls.py ----> #路由

from django.conf.urls import url
from django.contrib import admin
from hc import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'login/$', views.login),       
   #ip:port/   后面的内容就是这个路由的结果   即 127.0.0.1:8000/login

views.py #视图

for django.shortcuts improt render 

def login(request):
    if request.method == 'GET':
        data = 'hellow world'
        a = 'this my django project'
        return render(request, 'login.html', {'data': data, 'a': a})
        #return render(request, 'login.html', locals())       
        #locals() == {'data': data, 'a': a}   #简写
        #写法  render(request, 'templates模板','是views的返回值,可简写为 locals() ')

templates #模板 即HTML页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hc</title>
</head>
<body>
         <h1>{{ data }}</h1>       
         # {{ data }} 这种写法里面的 data  是上面views 视图的输出
         <p>{{ a }}</p>
</body>
</html>

models

简单的访问数据的内容

urls.py  -->  models.py    -->        views.py       -->         login.html
login      class UserInfo     models.UserInfo.objects.all    {%for i in sqlite%}

模块
models.py

#创建表和字段

class UserInfo(models.Model):     #创建一个类。继承了models.Model类  ---> 固定写法
    username =  models.CharField(max_length=32,null=True)  
    password =  models.CharField(max_length=32,null=True)

  #CharField 由字符或者文本组成的数据,需要存储少量的文本的用,CharField()
  #max_length --> 指定最大长度。null --> 是否允许为空

命令行执行两步: 修改和迁移

python manage.py makemigrations          # 修改数据库
python manage.py migrate                 # 迁移数据库

解析:
当models.py 修改过后,创建表和字段结构。即需要重新数据
makemigrations #修改数据库
migrate # 迁移数据库 ,保存

视图
views.py

from hc improt models       #加载刚创建的数据库

def login(request):
    if request.method == 'GET':
       obj_ite = models.UserInfo.object.all()  
           #这里的obj_ite就是一个queryset_list
           #obj_ite = models.UserInfo.object.filter(username='test')  
           # .filter()  也是 queryset_list 
           #使用filter() 来指定某一数据  
        for i in obj_ite:
            print  i.username    
            print  i.password
            #通过这个queryset_list 经过for 循环来点(.) 出来对象的值
    return render(request,'login.html',locals())

template 模板
login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hc</title>
</head>
<body>
        <h1> user </h1>
        {% for i in obj_ite  %}       #  循环判断都是用 {% if..for %}
          <div>
         <span>   {{ i.username }}   </span>        
         <span>   {{ i.password }}   </span>
          </div>
        {% endfor %} 

</body>
</html>

span 标签 <span> 标签被用来组合文档中的行内元素。
提示:请使用 <span> 来组合行内元素,以便通过样式来格式化它们。
注释:span 没有固定的格式表现。当对它应用样式时,它才会产生视觉上的变化。

sqlite 这是它的django自带的数据库
每个类会生成一个表

QuerySet 和 QuerySetList

QuerySet :
简单理解为 每条数据的对象,可以通过这个对象可以点(.) 出来它里面的值

QuerySetList :
这是个对象的列表,需要通过循环才能取值

queryset_list   ===>   object.all()
filter()        ===>   where

创建好数据后需要手动录入数据,需要在上方找到一个数据提交按钮 ,点击后才是写入数据

如果 sqlite DB 没有显示内容则需要安装一个东西
链接
https://blog.csdn.net/u013155359/article/details/81874665

django 基本命令

创建一个新的 django 项目
django-admin.py startproject <project_name>

创建一个新的 django 应用
python manage.py startapp <app_name>

启动django
python manage.py runserver ---> 默认为127.0.0.1:8000 可以是0.0.0.0:8000

数据同步操作
django 1.7以前的操作是
python manage.py syncdb

django 1.7以后的版本都是这样

python manage.py makemigrations   #修改数据库
python manage.py migrate          #迁移数据库

创建超级管理员admin
python manage.py createsuperuser
# create super user

修改 用户密码可以用:
python manage.py changepassword username

django 项目环境终端 ,可以用来测试

python manage.py shell    #对项目
python manage.py dbshell  #对数据库

更多命令
python manage.py

路由
urls.py

 urlpatterns = [
         url(正则表达式, views视图函数,参数,别名),
]

参数说明:

一个正则表达式字符串
一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
可选的要传递给视图函数的默认参数(字典形式)
一个可选的name参数

这是总路径

from django.conf.urls import url,include
from django.contrib import admin
from hc import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'login/', views.login),
    url(r'^api', include('hc01.urls'))    #include 用于拼接下级urls
]

以下都是子路径里的内容
从另个一应用导入

from django.conf.urls import url
from hc01 import views
urlpatterns = [
    url(r'^1.html', views.list),      #这样和上面的拼接,
    url(r'^2.html', views.list),    #  localhost/api/2.html
    url(r'^3.html', views.list),    #  localhost/api/3.html
]

hc01 应用里的 views.py

from django.shortcuts import render,HttpResponse    
                                   #HttpResponse() 不用写页面,直接返回括号里的内容
# Create your views here.
def hc01(request):
    return HttpResponse('is hc01')

def hc02(request):
    return HttpResponse('is hc02')

def hc03(request):
    return HttpResponse('is hc03')    
#HttpResponse() 不用写页面,直接返回括号里的内容

url 补充:

页面传参时

hc01 应用里的urls.py

from django.conf.urls import url
from hc01 import views
urlpatterns = [
    url(r'^(?P<num>[0-9]+)/1.html', views.list),  
         # (?P<num>[0-9]+) 正则匹配,匹配1-9多个数字'+'
    url(r'^(?P<num>[0-9]+)/2.html', views.list),  
         # 正则匹配前面可以不加'/'。 加了会有警告
    url(r'^(?P<num>[0-9]+)/3.html', views.list),   
]

hc01 应用里的 views.py
from django.shortcuts import render,HttpResponse    
                                  #HttpResponse() 不用写页面,直接返回括号里的内容
# Create your views here.
def hc01(request,num):
    print num
    return HttpResponse('is hc01')

def hc02(request,num):
    print num
    return HttpResponse('is hc02')      
      #传进来的参数num  都是字符串。如果是数字需要加int(num) 

def hc03(request,num):
    print num
    return HttpResponse('is hc03')   
          #HttpResponse() 不用写页面,直接返回括号里的内容

template 模板

  1. 模板语言 if 、 for 、 jquery 等
  2. 模板继承

成对出现 if ,for

if    
{if ...}
{endif}

for 
{for i in ..}
{endfor}

{% load staticfiles %}    #载入静态配置文件,这里只是路径

在 setings.py
STATIC_URL = '/static/' #这里可以改

语法格式: {{obj|filter:param}}

1  add              :   给变量加上相应的值
   
2  addslashes       :    给变量中的引号前加上斜线
  
3  capfirst         :    首字母大写
   
4  cut              :   从字符串中移除指定的字符
   
5  date             :   格式化日期字符串
   
6  default          :   如果值是False,就替换成设置的默认值,否则就是用本来的值
   
7  default_if_none  :  如果值是None,就替换成设置的默认值,否则就使用本来的值

实例:

value1="aBcDe"
{{ value1|upper }}<br>

value2=5
{{ value2|add:3 }}<br>

value3='he  llo wo r ld'
{{ value3|cut:' ' }}<br>

import datetime
value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}<br>

value5=[]
{{ value5|default:'空的' }}<br>

value6='<a href="#">跳转</a>'

{{ value6 }}

{% autoescape off %}
  {{ value6 }}
{% endautoescape %}

{{ value6|safe }}<br>

{{ value6|striptags }}

value7='1234'
{{ value7|filesizeformat }}<br>
{{ value7|first }}<br>
{{ value7|length }}<br>
{{ value7|slice:":-1" }}<br>

value8='http://www.baidu.com/?a=1&b=3'
{{ value8|urlencode }}<br>
    value9='hello I am yuan'

我的template

<!DOCTYPE html>
{% load staticfiles %}         #这里载入jQuery ,在setings.py里面设置
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hc</title>
    <script src="{% static 'jquery-3.3.1.min.js' %}"></script>     #在指定位置载入
</head>
<body>
    <h1> user meagess</h1>
    {% for item in obj_sqlite %}
        <div>
        <span>{{ item.username | upper}}</span>  
                            # '|'类似管道付,后面写的是一个方法、 upper:全部大写
        <span>{{ item.password | add:100}}</span> 
                            # add:100  是把前面的值增加100.前面的变量必须是数值
         <p></p>
        </div>
    {% endfor %}
    {{ abc }}
    <br>
    {{ abc | cut:' ' }}    # 使用了cut 移除指定的字符
    <br>
    {{ d }}
    <br>
    {{  d | date:'Y - m - d' }}   # 使用了date  把后端输出的时间格式化到前端
</body>
</html>

引入时间函数,才能调用。

import datetime
d = datetime.datetime.now()   #  .now()  为当前的时间

Dec. 17, 2018, 4:46 p.m. 

模板继承

在 template 里面定义
base.html
总的页面。所用子页面继承他的内容

<div>
    {% block content %}

     #这里是你需要的页面

    {% endblock %}
</div>


login.html   #子页面 里面写该页面需要的内容
{% extends 'base.html' %}
{% block content %}
    #你需要的内容 
{% endblock %}

simple_tag
当django的原生方法不够用时, 我可以自定方法来使用 这就是simple_tag

首先创建包 必须是 templatetags 这个名字
在这个包下创建一个py文件。名字可以自定义

创建了一个 my_tag.py 文件

my_tag.py

from django.template improt Library    #首先导入模块 固定导入

register = Library()      #这个实例化的对象必须叫 register 

@register.filter          # filter 方法只能传递两个参数。 这里就是装饰器了
def filter_func(x , y):   #.filter  方法只能传递两个参数,多了就不行
     return x+y


@register.simple_tag          # simple_tag 它可以接收多个参数
def simple_func(t,a,b,c):     # .simple_tag  方法 可以传递多个参数 

    return '2018-12-17'

这项目的名字 一定要再 setings.py 里面的 INSTALLED_APPS 里面

还有就是再html 里面去定义引用

{% load my_tag %}    
    #要再template 里去引入这个我创建的 my_tag.py 文件 

{{ test|filter_func:'123' }}   
    #  传入两个参数,这里用来拼接,因为上面的函数定义了 return x+y
    # test 当成第一个参数,'123' 当成第二个参数,传入 filter_func 这个方法里

{{ simple_func 't' 'a' 'b' 'c' }}   
    # 这里传入什么值 都return一个固定值,因为我方法里是这样定义了

simple_tag
总结一下

  1. 创建包必须的名字必须是 'templatetags' 这个名字

  2. 导入这个模块,Library模块是装饰器 'from django.template improt Library'

  3. 这个实例化的对象必须叫 'register' --> register = Library()

  4. 这项目的名字一定要再 setings.py 的 INSTALLED_APPS 里 有定义这个项目名

  5. 在template里面需要引用 写好的.py文件 '{% load my_tag %} '

Django - admin

view主要返回

render HttpResponse redirect

render 模板语言的渲染页面

HttpResponse 直接返回你想要的一个字符串,也可以是个对象

redirect 路由的跳转, 匹配括号内的地址

render函数

render(request, template_name[, context])

结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。

参数:
request:
    用于生成响应的请求对象。

template_name:
    要使用的模板的完整名称,可选的参数

context:
    添加到模板上下文的一个字典。默认是一个空字典。
    如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。

content_type:
    生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。

status:
    响应的状态码。默认为200。

总结:
render和redirect的区别:
1 . if render的页面需要模板语言渲染,需要的将数据库的数据加载到html,那么所有的这一部分除了写在yuan_back的视图函数中,必须还要写在login中,代码重复,没有解耦.

2 . the most important: url没有跳转到/yuan_back/,而是还在/login/,所以当刷新后又得重新登录.

admin

admin是django强大功能之一,它能共从数据库中读取数据,呈现在页面中,进行管理。默认情况下,它的功能已经非常强大,如果你不需要复杂的功能,它已经够用,但是有时候,一些特殊的功能还需要定制,比如搜索功能,下面这一系列文章就逐步深入介绍如何定制适合自己的admin应用。

如果你觉得英文界面不好用,可以在setting.py 文件中修改以下选项

LANGUAGE_CODE = 'en-us' #LANGUAGE_CODE = 'zh-hans'

python manage.py createsuperuser# 创建后台超级用户 superuser

输入 用户名 和 密码

admin.py

from hc_learning improt models# 把 我自己写的 models导入

两种方式
1 使用register的方法

admin.site.register(Book,MyAdmin)

2 使用register的装饰器

@admin.register(Book)

第一种
register

admin.site.register(models.UserInfo) # 这样使用它自带的封装

还要需要把 app 注册到 settings.py 里面

掌握一些常用的设置技巧

list_display:      指定要显示的字段
search_fields:     指定搜索的字段
list_filter:       指定列表过滤器
ordering:         指定排序字段

这么用

class MyAdmin(admin.ModelAdmin):
    list_display = ('name','username',"password")   #括号内的是字段名

admin.site.register(models.UserInfo,MyAdmin)    #MyAdmin  这里要把这个类```当参数传进去

Django ORM

ORM基础
如果要使用真 mysql 需要去settings 里面将DATABASES 修改成如下

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.mysql', 

        'NAME': 'books',     #你的数据库名称

        'USER': 'root',      #你的数据库用户名

        'PASSWORD': '',      #你的数据库密码

        'HOST': '',          #你的数据库主机,留空默认为localhost

        'PORT': '3306',      #你的数据库端口

    }

注:
NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建

USER和PASSWORD分别是数据库的用户名和密码。

设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。

然后,启动项目,会报错:no module named MySQLdb

这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL

所以,我们只需要找到项目名文件下的init,在里面写入:

需要在项目名文件下的init.py 在里面写入

import pymysql
pymysql.install_as_MySQLdb()
#重点

增加数据表 就在models.py 里面写

class UserInfo(models.Model):
    name = models.CharField(max_length=32,null=True,blank=True,verbose_name='姓名')
    username = models.CharField(max_length=32,null=True)
    password = models.CharField(max_length=32,null=True)
    # num = models.IntegerField(default=0)   #定义了一个数字类型,默认值为0
    def func(self):
        return 'add you baba'
    def __str__(self):      #查询数据库 返回字符串
        return self.name

class School(models.Model):                #null=True,blank=True  要用就要一起用 
    name = models.CharField(max_length=32,null=True,blank=True,verbose_name='学校名')
    #null=True 可以为空, blank 针对admin使用的时候这两个同时使用可以为空。verbose_name 显示信息
    # mac = models.URLField(max_length=128,null=True,blank=True,verbose_name='地址')
    # email = models.EmailField(max_length=128,null=True,blank=True,verbose_name='邮箱')
    # true_false = models.BooleanField(max_length=128,null=True,blank=True,verbose_name='是否')
    # date = models.DateField(verbose_name='时间')
    # cla = models.ForeignKey(to='Class',default=1) #default='1',设置默认值 # ForeignKey  一对多类型。
    #自动生成ID -->  cla_id ,指向了Class 类,它里面会自己生成ID,是class的ID
    def __str__(self):
        return self.name

class Number(models.Model):
    num = models.OneToOneField(to='UserInfo')   # 一对一的一一对应关系
    # OneToOne 类型对应 UserInfo  ,每个学生都有一个学号
    def __str__(self):
        return self.num

class Class(models.Model):
    xuexiao = models.ForeignKey(to='School', default=1)
    name = models.CharField(max_length=128,null=True,blank=True,verbose_name='班级')
    user = models.ManyToManyField(to='UserInfo',related_name='clauser')  # 多对多关系
     # class_to_userinfo --> id , UserInfo_id , class_id   三张表
    def __str__(self):
        return self.name

def __str__(self):

__str__()方法,返回一个好看的字符串就可以了:

>>> class Student(object):
...     def __init__(self, name):
...         self.name = name
...     def __str__(self):
...         return 'Student object (name: %s)' % self.name
...
>>> print Student('Michael')
Student object (name: Michael)

这样打印出来的实例,不但好看,而且容易看出实例内部重要的数据。

但是细心的朋友会发现直接敲变量不用print,打印出来的实例还是不好看:

>>> s = Student('Michael')
>>> s
<__main__.Student object at 0x109afb310>

这是因为直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。

解决办法是再定义一个__repr__()。但是通常__str__()__repr__()代码都是一样的,所以,有个偷懒的写法:

class Student(object):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return 'Student object (name=%s)' % self.name
    __repr__ = __str__

__str__() 
返回用户看到的字符串,
__repr__() 
返回程序开发者看到的字符串,
__repr__() 
是为调试服务的。

增删改查-----查询

两种查询方式
第一种 .all()
第二种 .get(id=?) 或者 .filter() 里有 .first() 和 .last()

.get 取的是 queryset 集合

.filter 取的是 queryslit 列表

查的时候推荐用 .filter

models.School.objects.all()#查询所有 是一个queryslit 里面每一个值都是queryset

b = models.School.objects.all() #返回所有信息 all()出来的是 queryset_list
这个是个list的里面有很多的queryset

models.School.objects.all() 

b = models.School.objects.all()  
print (b)                      # 打印这个输出QuerySet
print (type(b))               #看这个是什么类别
for i in b:
   print (i.name,type(i),i)   #循环输出这个list里面的信息


print (b)   
<QuerySet [<School: 你爸爸大学>, <School: 五道口职业学院>]>

print (type(b))
<class 'django.db.models.query.QuerySet'>

for --> print (i.name,type(i),i)   # 这里输出的是 类
你爸爸大学 <class 'hc.models.School'> 你爸爸大学
五道口职业学院 <class 'hc.models.School'> 五道口职业学院




c = models.School.objects.get(id=1)    # get通过id 拿到的是queryset 的值,只能取ID

print (c)    --->   你爸爸大学 <class 'hc.models.School'>



d = models.School.objects.filter(name='五道口职业学院').first()
e = models.School.objects.filter(name='你爸爸大学').last() 


print (d,e)    --->   五道口职业学院, 你爸爸大学



d = models.School.objects.filter(name='abc').first()
e = models.School.objects.filter(name='avx').last()   #如果没有这个值 这会返回 None


print (d,e)    --->  None None




以字典的形式去取值

dict1 = {'name':'hc'}

ojb = models.School.object.filter(**dict1).first()

print (ojb)    --->   None


dict1 = {'name':'你爸爸大学'}

ojb = models.School.object.filter(**dict1).first()

print (ojb)    --->   你爸爸大学

查询

查询相关API:

  1. filter(**kwargs): 它包含了与所给筛选条件相匹配的对象

  2. all(): 查询所有结果

  3. get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。

-----------下面的方法都是对查询的结果再进行处理:比如 objects.filter.values()--------

  1. values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 ;-->拿到库内 固定列内的 值作为 一对 key value ;如果条件是多个,那就拿到多对,整体是一个列表

  2. exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象

  3. order_by(*field): 对查询结果排序

  4. reverse(): 对查询结果反向排序

  5. distinct(): 从返回结果中剔除重复纪录

  6. values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列;相比于 values 左后是一个 元祖,不是字典

  7. count(): 返回数据库中匹配查询(QuerySet)的对象数量。

  8. first(): 返回第一条记录

  9. last(): 返回最后一条记录

  10. exists(): 如果QuerySet包含数据,就返回True,否则返回False

双下划线(__)之单表条件查询

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感

models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and

startswith,istartswith, endswith, iendswith,

增,改,删 (1,2)
create ,update, delete

增加 create
create方式一:   Author.objects.create(name='Alvin')

create方式二:   Author.objects.create(**{"name":"alex"})

save方式一:     author=Author(name="alvin")
                        author.save()

save方式二:     author=Author()
                        author.name="alvin"
                        author.save()

改的第一种方式 update ,推荐

第二种方式 通过get ,找不到会报错
需要先用get查,然后使用点,点出来再重新修改,最后save() 保存 .name()

obj_c = models.School.objects.cteate(name='hc')    #name 是字段信息
print (obj_c)


obj_d = models.School.objects.filter(name='hc').delete()   #先查询,再删
print (obj_d)

改的第一种方式 update ,推荐

obj_u = models.School.objects.filter(name='hc').updata(name='hc1')   #先查询,再修改
print (obj_u)   # 这里只会拿到修改的条数

改的第二种方式 ,通过get ,如果找不到会报错

obj_g = models.School.objects.get(name='hc')   #先通过get找到对应的字段,如果找不到会报错
obj_g.name='hc2'              #  用这个queryset对象再字段点出来 --> .name   再重新赋值给它,即为修改  
obj_g.save()           #最后用到这个 save()  方法将其保存写入到数据库

注意:

  1. 第二种方式修改不能用get的原因是:update是QuerySet对象的方法,get返回的是一个model对象,它没有update方法,而filter返回的是一个QuerySet对象(filter里面的条件可能有多个条件符合,比如name='alvin',可能有两个name='alvin'的行数据)。

  2. 在“插入和更新数据”小节中,我们有提到模型的save()方法,这个方法会更新一行里的所有列。 而某些情况下,我们只需要更新行里的某几列。

    dic = {'name':'hc1'}


    # 增加  'hc','hc1'
    for i in ['hc','hc1']:
        obj_c = models.School.objects.create(name=i)   
         #name 是字段信息,对应字段直接加数据
        print (obj_c,type(obj_c))

    # 删除   hc 
    obj_d = models.School.objects.filter(name='hc').delete()    
     #先查询,再删
    print (obj_d,type(obj_d))    
    # 这里只会拿到删除的条数

    # 更新 1  update  -->  hc2
    obj_u = models.School.objects.filter(**dic).update(name='hc2') 
     #先查询,再修改
    print (obj_u,type(obj_u))      # 这里只会拿到修改的条数

    # 更新 2  get     -->  hc3
    obj_g = models.School.objects.get(name='hc2')    
    #先通过get找到对应的字段,如果找不到会报错
    obj_g.name = 'hc3'  
     #  用这个queryset对象再字段点出来 --> .name   再重新赋值给它,即为修改
    obj_g.save()    
     #最后用到这个 save()  方法将其保存写入到数据库
    print(obj_g,type(obj_g))



#输出
print (obj_c,type(obj_c))
    hc <class 'hc.models.School'>
    hc1 <class 'hc.models.School'>

print (obj_d,type(obj_d))  
    (1, {'hc.School': 1}) <class 'tuple'>     #修改的条数

print (obj_u,type(obj_u))
    1 <class 'int'>        #修改的条数

print(obj_g,type(obj_g))
    hc3 <class 'hc.models.School'>

-0。0|||、 有问题欢迎来找我 撩骚~~~~~
原文地址:https://www.cnblogs.com/huidou/p/10757614.html