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)   
, ]>

print (type(b))


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




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

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



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 
    hc1 

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

print (obj_u,type(obj_u))
    1         #修改的条数

print(obj_g,type(obj_g))
    hc3 

你可能感兴趣的:(Django ORM)