我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python基础(Django三——Model)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python基础(Django三——Model)

本篇内容接上篇Python基础(Django二)


七、Model

1、说明:

Model是Django为方便程序操作数据库而诞生的,使用的是ORM模式。

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的关系,将程序中的对象自动持久化到关系数据库中。


2、使用:

 2-1、创建Model(编辑应用目录下的models.py)

from django.db import models

class Author(models.Model):    #定义一个类(表),类名即是表名
    #定义一个叫first_name的字段(列),字段类型为字符串类型,参数设置最大长度为32个字节
    first_name = models.CharField(max_length=32)	
    last_name = models.CharField(max_length=32)
    email = models.EmailField(null=True,blank=True)     #字段类型为邮箱,会有格式验证
    def __unicode__(self):	    #定义查询类的数据时显示的值
        return '%s %s'%(self.first_name,self.last_name)

字段类型:

1、models.AutoField  自增列 = int(11)

  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。

2、models.CharField  字符串字段

  必须 max_length 参数

3、models.BooleanField  布尔类型 =tinyint(1)

  不能为空

4、models.ComaSeparatedIntegerField  用逗号分割的数字 =varchar

  继承CharField,所以必须有 max_lenght 参数

5、models.DateField  日期类型 date

  对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。

6、models.DateTimeField  日期类型 datetime

  同DateField的参数

7、models.Decimal  十进制小数类型 = decimal

  必须指定整数位max_digits和小数位decimal_places

8、models.EmailField  字符串类型(正则表达式邮箱) =varchar

  对字符串进行正则表达式

9、models.FloatField  浮点类型 = double

10、models.IntegerField  ×××

11、models.BigIntegerField  长×××

  integer_field_ranges = {

    'SmallIntegerField': (-32768, 32767),

    'IntegerField': (-2147483648, 2147483647),

    'BigIntegerField': (-9223372036854775808, 9223372036854775807),

    'PositiveSmallIntegerField': (0, 32767),

    'PositiveIntegerField': (0, 2147483647),

  }

12、models.IPAddressField  字符串类型(ip4正则表达式)

13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)

  参数protocol可以是:both、ipv4、ipv6

  验证时,会根据设置报错

14、models.NullBooleanField  允许为空的布尔类型

15、models.PositiveIntegerFiel  正Integer

16、models.PositiveSmallIntegerField  正smallInteger

17、models.SlugField  减号、下划线、字母、数字

18、models.SmallIntegerField  数字

  数据库中的字段有:tinyint、smallint、int、bigint

19、models.TextField  字符串=longtext

20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]

21、models.URLField  字符串,地址正则表达式

22、models.BinaryField  二进制

23、models.ImageField   图片

24、models.FilePathField 文件


参数:

1、null=True

  数据库中字段是否可以为空

2、blank=True

  django的 Admin 中添加数据时是否可允许空值

3、primary_key = False

  主键,对AutoField设置主键后,就会代替原来的自增 id 列

4、auto_now 和 auto_now_add

  auto_now   自动创建---无论添加或修改,都是当前操作的时间

  auto_now_add  自动创建---永远是创建时的时间

5、choices

GENDER_CHOICE = (

        (u'M', u'Male'),

        (u'F', u'Female'),

    )

gender = models.CharField(max_length=2,choices = GENDER_CHOICE)

6、max_length

7、default  默认值

8、verbose_name  Admin中字段的显示名称

9、name|db_column  数据库中的字段名称

10、unique=True  不允许重复

11、db_index = True  数据库索引

12、editable=True  在Admin里是否可编辑

13、error_messages=None  错误提示

14、auto_created=False  自动创建

15、help_text  在Admin中提示帮助信息

16、validators=[]

17、upload-to

 

 #相关命令

 python manage.py validate   #用来检测models.py语法的正确性

 python manage.py makemigrations

 python manage.py migrate   #根据代码中定义的类来自动创建数据库表


 2-2、操作数据库表

from app01 import models

# 增 #
#第一种:
models.Author.objects.create(first_name='zhang',last_name='san',email='z@test.com')

#第二种:可以接受字典类型的数据
dic = {'first_name': 'li', 'last_name': 'si', 'email': 'z@test.com'}
models.Author.objects.create(**dic)

#第三种:
obj = models.Author(**dic)
obj.save()

# 查 #
models.Author.objects.all()	#获取Author表里的所有数据

#过滤查询
filter()方法获取的是一个列表,get()方法获取的是单个对象

models.Author.objects.get(first_name='zhang')    #Author是表名称,first_name是字段名称,zhang是查询的关键字

models.Author.objects.filter(last_name='san')	

models.Author.objects.filter(first_name='zhang', last_name='san') #查询条件可以有多个	

models.Author.objects.exclude(first_name='zhang') #查询first_name不等于zhang的

models.Author.objects.filter(first_name='zhang').count() #获取满足查询条件的数据个数

#多重查询
models.Author.objects.filter(first_name='zhang').order_by("email")

#限制查询
models.Author.objects.order_by('first_name')[0]	#取查询结果QuerySet的第一个值

#排序
models.Author.objects.order_by("first_name")   #根据某一个字段值对结果排序
models.Author.objects.order_by("first_name","last_name") #根据多个字段排序,第二个字段会在第一个字段值相同的情况下被使用到
models.Author.objects.order_by("-first_name")	#逆向排序,字段前面加减号-前缀
  
#利用双下划线将查询字段和相应操作连接起来(摘自其他博客)
# 大于,小于
models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

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

# contains
models.Tb1.objects.filter(name__contains="ven")	  #用于模糊匹配name字段。
models.Tb1.objects.filter(name__icontains="ven")  #icontains大小写不敏感
models.Tb1.objects.exclude(name__icontains="ven") #取反

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

# 改 #
# 在查询的基础上增加一个修改操作
# 第一种:
models.Author.objects.filter(last_name='si').update(last_name='SI')

# 第二种:可以接受字典类型的数据
dic = {'first_name': 'li', 'last_name': 'si', 'email': 'z@test.com'}
models.Author.objects.filter(last_name='si').update(**dic)

# 第三种:
obj = models.Author.objects.get(last_name='si')
obj.email = 'new@test.com'
obj.save()

# 删 #
# 在查询的基础上增加一个删除操作
models.Author.objects.filter(last_name='san').delete()

    

 2-3、连表结构

   说明:

    Django的ORM有多种关系:

     一对一:一个只属于一个

     一对多:一个属于多个

     多对多:一个既有很多个,又属于很多个

    各自定义的方式为 :

       一对一: models.OneToOneField(其他表)

       一对多: models.ForeignKey(其他表)

       多对多: models.ManyToManyField(其他表)    

    应用场景:

      一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)
       例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。

       多对多:在某表中创建一行数据是,有一个可以多选的下拉框
       例如:创建用户信息,需要为用户指定多个爱好

       一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了


  举例:

 #models.py

# -*- coding:utf-8 -*-
from __future__ import unicode_literals
from django.db import models

# Create your models here.

# OneToMany example 1
class UserType(models.Model):
    caption = models.CharField(max_length=32)
    def __unicode__(self):
        return self.caption

class UserInfo(models.Model):
    user_type = models.ForeignKey(UserType)
    username = models.CharField(max_length=32)
    age = models.IntegerField()

    def __unicode__(self):
        return self.username

# OneToMany example 2

class MyUser(models.Model):
    username = models.CharField(max_length=16)
    password = models.CharField(max_length=16)

    def __unicode__(self):
        return self.username

class News(models.Model):
    title = models.CharField(max_length=32)
    content = models.CharField(max_length=32)

    def __unicode__(self):
        return self.title

class Favor(models.Model):
    user_obj = models.ForeignKey(MyUser)
    new_obj = models.ForeignKey(News)

    def __unicode__(self):
        return "%s --> %s"%(self.user_obj.username,self.new_obj.title)

# ManyToMany example 1

class Host(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField()
    def __unicode__(self):
        return self.hostname

class HostAdmin(models.Model):
    username = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    host = models.ManyToManyField(Host)
    def __unicode__(self):
        return self.username

# ManyToMany example 2
'''手动创建多对多关系表,不需要Django自动创建,优点是第三张表的字段可以自定义'''
class Host2(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField()
    def __unicode__(self):
        return self.hostname

class HostAdmin2(models.Model):
    username = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    host = models.ManyToManyField(Host2,through="HostRelation")
    def __unicode__(self):
        return self.username

class HostRelation(models.Model):
    host_obj = models.ForeignKey(Host2)
    admin_obj = models.ForeignKey(HostAdmin2)


 #views.py

# -*- coding:utf-8 -*-
from django.shortcuts import render,HttpResponse
from app01 import models

# Create your views here.

def user_info(request):
   # 一对多 #

   # models 为"OneToMany example 1"
   #创建数据#
   #第一种: ForeignKey所在的字段加 _id 进行直接赋值
   models.UserInfo.objects.create(username='test1',age=13,user_type_id=1) #user_type_id是一对多关系表中Django自动生成的字段名
   #第二种:ForeignKey所在的字段使用对象进行赋值
   user_type_obj = models.UserType.objects.get(id=2)                          #先从user_type表中获取一个对象
   models.UserInfo.objects.create(username='test2',age=14,user_type=user_type_obj)    #使用刚获取的对象进行赋值(注意字段名称)

   #正向查找#(就是从ForeignKey所在字段的表去查询数据)
   #单表查询
   models.UserInfo.objects.filter(username='test1')   #查询UserInfo表中username字段值是‘test1’的数据

   # 跨表查询,通过ForeignKey所在的字段 + 双下划线 + 被跨的表中的字段来查询(ForeignKey所在的字段user_type是一个对象)
   # models.UserInfo.objects.filter(user_type__caption='CEO') #查询UserInfo表中user_type对象中caption字段的值是CEO的数据
   ret = models.UserInfo.objects.filter(user_type__id=2)     #语法同上,ret是一个QuerySet对象
   for i in ret:
      #打印获取到的QuerySet对象中每个值的username属性,以及user_type对象的caption属性(跨表操作时,查询使用__(双下划线),访问字段使用.(点))
       print i.username,i.user_type.caption

   #反向查找#(就是从被ForeignKey字段关联的表去查询数据)
   #单表查询
   line = models.UserType.objects.get(id=1)   #从UserType表中获取一个id=1的对象

   #跨表查询
   # 第一种: 通过被跨的表的小写表名 + 双下划线 + 要查询的字段  来查询
   models.UserType.objects.get(userinfo__username='test1')   #userinfo是django自动在UserType表中创建的一个对象,也就是对端表的小写表名
   # 第二种:
   line.userinfo_set.filter(username='test1')
      # line是一个对象(参考如上的获取条件)
      # userinfo_set是UserInfo表中满足line条件的所有值。也就是UserInfo表中所有user_type=1 的值
      # 本次查询的目标是:通过UserType表去反向查询UserInfo表中user_type=1且username=test1的所有数据
   line.userinfo_set.all().count()    #计算满足查询条件的数据个数

   #多级查询, models 为"OneToMany example 2"
   ret = models.News.objects.filter(favor__user_obj__username='zhangsan')
      # 查询的表顺序为 News -> Favor -> MyUser
      # 先是反向跨表查询:通过News表查询Favor表中的user_obj对象
      # 再是正向跨表查询:通过user_obj对象查询Myuser表中username字段值为zhangsan的用户
      # 最终得到zhangsan赞过的所有文章
   for i in ret:
      print i.title              #文章的标题
      print i.favor_set.all().count()    #文章一共几个赞

   # 多对多 #
   #  models为 "ManyToMany example 1"

   models.HostAdmin.objects.create(username='a1',email='1@qq.com')    #创建一个用户,管理的主机为空
   #正向添加#
   admin_obj = models.HostAdmin.objects.get(username='a1')   #先获取一个用户对象
   host_list = models.Host.objects.filter(id__lt=3)          #再获取多个主机对象
   admin_obj.host.add(*host_list)                            #为一个用户添加多个可管理的主机

   #反向添加#
   host_obj = models.Host.objects.get(hostname='h2')       #先获取一个主机对象
   admin_list = models.HostAdmin.objects.filter(id__gt=1)  #再获取多个用户对象
   host_obj.hostadmin_set.add(*admin_list)                 #为一个主机添加多个用户,注意这里用到了hostadmin_set

   #正向查询#
   admin_obj = models.HostAdmin.objects.get(username='a1')    #先获取一个用户对象
   host_list = admin_obj.host.all()                     #查询该用户管理的所有主机
   for i in host_list:
      print i.hostname,i.port

   #反向查询#
   host_obj = models.Host.objects.get(hostname='h2')     #先获取一个主机对象
   admin_list = host_obj.hostadmin_set.all()           #查询该主机的所有管理员
   for i in admin_list:
      print i.username,i.email

   #自定义多对多关系#
   # models为 "ManyToMany example 2"
   # 添加数据
   models.HostRelation.objects.create(
       host_obj_id = 1,    #等于 host_obj = models.Host2.objects.get(id=1)
       admin_obj_id = 1,   #等于 admin_obj = models.HostAdmin2.objects.get(id=1)
   )

   # 查询
   # relation_list = models.HostRelation.objects.all()
   relation_list = models.HostRelation.objects.filter(admin_obj__username='user1')
   #通过HostRelation表查询用户名是user1的所有数据
   for i in relation_list:
      print i.admin_obj.username #用户名
      print i.host_obj.hostname  #用户所管理主机的主机名

   # Django 的F #
   # 对对象中某一列值的操作
   from django.db.models import F
   models.Host.objects.filter(hostname='h2').update(port=F('port')+1) #把Host表中所有hostname=h2的数据的port值加1
   models.Host.objects.update(port=F('port')+1)   #把Host表中所有的port值加1

   # Django 的Q #
   # 对象的复杂查询
   from django.db.models import Q

   #单Q多条件查询
   q1 = Q()            #创建一个Q对象
   q1.connector = 'OR'       #定义查询条件是 '或'
   q1.children.append(('hostname__contains','h2'))       #children添加的是元祖,查询字段支持使用一些自带的方法
   q1.children.append(('hostname','h3'))           #添加多个查询条件
   q1.children.append(('hostname','h6'))
   ret_list = models.Host.objects.filter(q1)        #使用q1对象进行查询(针对Host表)
   for i in ret_list:
      print '%s->%s'%(i.hostname,i.port)

   #多Q多条件查询
   con = Q()     #创建一个外层Q对象,Q可以嵌套
   q2 = Q()
   q2.connector = 'OR'
   q2.children.append(('port','23'))        #查询port字段值等于23的数据
   q2.children.append(('port__gt','23'))     #查询port字段值大于23的数据

   con.add(q1,'AND')     #把q1添加到之前定义的最外层的Q对象中,查询条件是 '和'
   con.add(q2,'AND')     #把q2添加到之前定义的最外层的Q对象中,查询条件是 '和'

   ret_list = models.HostAdmin.objects.filter(con)       #查询的结果是同时满足q1和q2条件的数据(针对HostAdmin表)
   for i in ret_list:
      print '%s->%s'%(i.hostname,i.port)

   #多Q多条件跨表查询
   q1.children.append(('username','a1'))
   q1.children.append(('username','a2'))
   q1.children.append(('username','a3'))
   q2.children.append(('host__hostname','h5'))       #支持跨表查询,host是表名 + 双下划线 + 查询的字段

   con.add(q1,'AND')
   con.add(q2,'AND')

   ret_list = models.HostAdmin.objects.filter(con)       #查询用户名是a1或a2或a3 且管理主机名为h5的用户(针对HostAdmin表)
   for i in ret_list:
      print i.username


   return HttpResponse('ok')    #无特别意义,只是函数需要一个返回值。


博客的部分内容和思路整理自武沛齐的博客。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python基础(Django三——Model)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python基础(Django)

介绍Django之前,先来明确几个基础概念:1、什么是Web框架?    Web框架其实是建立web应用的一种方式,它为应用程序提供一套程序框架,这样开发者可以专注于编写清晰、易维护的代码,而无需从头做起。    他们基本上都以相同的方式工
2023-01-31

Python随笔(三)、python基础

一、练习:#!usr/bin/env python #-*- coding:utf-8 _*-  """ @author:Administrator @file: dictionary.py@time: 2017/11/19 """'''有
2023-01-31

Python基础语法(三)

1. 数值型数据结构1.1 要点在之前的博客也有提到,数值型数据结构在这里就不过多介绍了。在这里提及一些需要知道的知识点。int、float、complex、bool都是类,1\3.14\2+3j都对象(即实例)。这也符合Python一切皆
2023-01-31

python之基础篇(三)

防伪码:忘情公子著python编程基础及编程风格:  语句和语法    注释:      #:可以从一行的任何地方开始    续行:      \:只能在行尾      ''':闭合操作符,单一语句跨多行。实现多行注释、内置文档等功能   
2023-01-31

python框架django基础指南

Django简介: Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的框架模式,即模型M,视图V和控制器C。不过在Django实际使用中,Django更关注的是模型(Model)、模板(Template)和视图
2022-06-04

django基础(一)

项目的创建和启动(venv3) [vagrant@localhost ~]$ cd /vagrant/(venv3) [vagrant@localhost vagrant]$ django-admin startproject devops
2023-01-31

Python全栈开发之Django基础

No.1 MVC&MTVMVCM全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作V全拼为View,用于封装结果,生成页面展示的html内容C全拼为Controller,用于接收请求,处理业务逻辑,与Mode
2023-01-31

django模型层(model)进行建表、查询与删除的基础教程

前言 在django的框架设计中采用了mtv模型,即Model,template,viewer Model相对于传统的三层或者mvc框架来说就相当对数据处理层,它主要负责与数据的交互,在使用django框架设计应用系统时,需要注意的是dja
2022-06-04

python基础知识(三)set集合

set集合不同元素组成无序集合中元素必须是不可变的类型s={1,2,3,4,5,6}#增加s.add("s")#清空s.clear()#弹出s.pop()#删除指定值,删除元素不存在报错s.remove("s")#删除指定值,删除元素不存在
2023-01-31

Django基础之(十)DRF

简介官方文档RequirementsREST framework requires the following:Python (2.7, 3.4, 3.5, 3.6, 3.7)Django (1.11, 2.0, 2.1)The follo
2023-01-31

三、python基础之条件和循环

目录一.if语句1.1 功能1.2 语法1.2.1:单分支,单重条件判断1.2.2:单分支,多重条件判断1.2.3:if+else1.2.4:多分支if+elif+else1.2.5:if语句小结1.3 案例1.4 三元表达式二.while
2023-01-31

Python基础-Python基础使用

上篇文章 Python基础-初识Python 我们已经知道了什么是Python,Python的用处、和Python的解释器、Python的安装,这篇文章,我们主要讲Python的使用入门本文防盗链:http://python789.blog
2023-01-31

django-模板层基础2

1、模板的导入 {% include 模板名%} 首先在你的的项目中,需要很多地方用到同一个组件(相对于头部,你进行每个页面的切换,网页最上面的头  部不需要改变),那么这样我们可以把那个头部重新写在一个模板中,其他每个页面需要
2023-01-30

python django系列(三)

数据库,里面有各种宝贝,一个没有数据库的网站,提供的功能非常有限连接数据库mysql是最常用的数据库,这里将django和mysql连接。安装:easy_install MySQL-python 或pip install MySQL-py
2023-01-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录