zoukankan      html  css  js  c++  java
  • 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|||、 有问题欢迎来找我 撩骚~~~~~
  • 相关阅读:
    mysql数据库的相关练习题及答案
    数据库一
    python的协程
    jquery的常用知识点
    diehard–让你的程序更健壮
    迷宫塔生成工具
    编程解决谁是凶手的问题
    ClojureScript实现xpath定位器生成-1
    使用ClojureScript进行chrome扩展开发
    AES CBC模式下的Padding Oracle解密
  • 原文地址:https://www.cnblogs.com/huidou/p/10757614.html
Copyright © 2011-2022 走看看