web框架详解之三Modal

一、Modal操作之创建表,添加数据

1、	配置Django中settings的设置连接mysql数据库,然后在mysql数据库中创建库
2、	在models中创建表。继承Model
3、	在settings的INSTALLED_APPS的设置中写上自己创建的app,这里是app01,注意后面要加上逗号
4、	在run project Task 中执行makemigrations  和migrate 使数据库表生成

 

from django.db import models

# Create your models here.
class UserType(models.Model):
    nid=models.AutoField(primary_key=True)
    caption=models.CharField(max_length=16)

class UserInfo(models.Model):
    user=models.CharField(max_length=32)
    email=models.EmailField(max_length=31)
    pwd=models.CharField(max_length=64)
    #创建外键让type和这个表建立联系,这里注意UserType必须要在这个上面,不然出错,或者让下面的外键在括号中引起来
    user_type=models.ForeignKey(UserType)
models文件

settings文件需要添加如下:

然后和project同名的__init__.py里面添加:

然后执行makemigrations  和migrate  这样mysql库就连接上了,(注意首先创建库)。并且创建了表

二、往表中添加数据

首先添加路由

2、然后在视图文件中添加视图函数

首先在view文件中导入models。,然后下面是分别往两张表中添加数据

单表查询:

from django.db import models

# Create your models here.


class UserInfo(models.Model):
    user=models.CharField(max_length=32)
    email=models.EmailField(max_length=31)
    pwd=models.CharField(max_length=64)
    #创建外键让type和这个表建立联系,这里注意UserType必须要在这个上面,不然出错,或者让下面的外键在括号中引起来
    user_type=models.ForeignKey('UserType')


class UserType(models.Model):
    nid = models.AutoField(primary_key=True)
    caption = models.CharField(max_length=16)
    p=models.ForeignKey('p')

class p(models.Model):
    name=models.CharField(max_length=16)


    #这个方法会使输出什么,那么就返回什么,一般在后台做显示用的
    #这个方法在python2.7中是__unicode__方法
    # def __str__(self):
    #     return "s%-s%" %(self.nid,self.caption)
models.py文件

 

userinfo表

usertype表

连表操作

了不起的双下划线之外键反向查找

上面是正向查找,下面是反向查找

通过_set.all()操作获取数据

数据库:

from django.db import models

# Create your models here.


class UserInfo(models.Model):
    user=models.CharField(max_length=32)
    email=models.EmailField(max_length=31)
    pwd=models.CharField(max_length=64)
    #创建外键让type和这个表建立联系,这里注意UserType必须要在这个上面,不然出错,或者让下面的外键在括号中引起来
    user_type=models.ForeignKey('UserType')


class UserType(models.Model):
    nid = models.AutoField(primary_key=True)
    #unique=True,让其数据不能重复
    caption = models.CharField(max_length=16,unique=True)

视图函数操作

from django.shortcuts import render,HttpResponse

from app01 import models
# Create your views here.
def index(request):
############################反向查找############################
    #获取这张表的用户类型对象,这里first()因为是管理员这一项是一条数据的对象

   obj=models.UserType.objects.filter(caption="管理员").first()
    print(obj)  #userType object
    print(obj.nid) #1
    #表明_set.all()获取用户是管理员的所有的数据
    print(obj.userinfo_set.first())

	a=obj.userinfo_set.all()  # UserInfo
for i in a:
    print(i,i.user,i.email,i.pwd) # object pyrene pyrene@a 123

下面是方法二
ob=models.UserType.objects.all().values('nid','userinfo__user')
print(ob)#[{'nid': 1, 'userinfo__user': 'pyrene'}, {'nid': 2, 'userinfo__user': None}
return HttpResponse("ok")

    return HttpResponse("ok")

外键操作梳理

连表操作(一对多):

正向查找:  获取另一张表中的内容

tet=userinfo.object.all()

for item in ret:

         item.id

         item.外键字段.caption

上面不能用双下划线,因为这里的item是用的对象,对象跟其他表有关联,这个对象代表当前数据这里用点

语句

                  tb.objects.filter(字段=’’,外键字段__caption).values(‘外键字段__caption’)

用下划线的时候:  双下划线是帮助开发者跨表用的,跨表获取值

在语句中filter,或者values中用双下划线

 

         反向查找: 获取另一张表中的内容

方法一—set.all()

         这里只能用get方法              

obj=UserType.abject.get(nid=1)

         obj.nid

         obj.caption

         result=obj.表名_set.all()  #获取管理员相关的所有用户,也就是另一张表中的相关的所有用户,想要获取某一个需要遍历

         for i in result:

                   print(i,i.item,i.email,i.pwd)

 

方法二、 在queryset中加入  表名__user

         userType.objects.all().values(‘nid’,’表名__user’)  #获取和nid相关另一张表的所有信息

如:

ob=models.UserType.objects.all().values('nid','userinfo__user')
print(ob)#[{'nid': 1, 'userinfo__user': 'pyrene'}, {'nid': 2, 'userinfo__user': None}

上面方法有:get、all、filter、双下划线(跨表取值)、_set
View Code

 

一对一结构的原理

一对一是人为构建的

from django.db import models
# Create your models here.
class UserInfo(models.Model):
    user=models.CharField(max_length=32)
    email=models.EmailField(max_length=31)
    pwd=models.CharField(max_length=64)
    # user_type=models.ForeignKey('UserType',unique=True)
    user_type=models.OneToOneField('UserType')

class UserType(models.Model):
    nid = models.AutoField(primary_key=True)
    #unique=True,让其数据不能重复
    caption = models.CharField(max_length=16,unique=True)

一对一关系:

创建外键的时候加入unique=True

或者是用OneToOneField

解释:

如上面建立两张表,并且让第一章表和第二章表产生关系,让第一张表中user为pyrene对应为第二张表的caption为管理员.这个时候在创建一个user为p,如果让其对应第二张表caption为管理员就会出错。但是可以为超级管理员。

多对多之创建表

1、首先创建Models表

下面的是传统的创建Models表的方法,还有Django自己的方法

from django.db import models
class HoseToGroup(models.Model):
    hgid=models.AutoField(primary_key=True)
    host_id=models.ForeignKey('Host')
    group_id=models.ForeignKey('Group')


class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32)
    ip=models.CharField(max_length=32)

class Group(models.Model):
    gid=models.AutoField(primary_key=True)
    name=models.CharField(max_length=16)

Django自己的方法:用ManyToManyField的方法

 

class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32)
    ip=models.CharField(max_length=32)
    #在这个表或者下个表方法中用ManyToManyField就是创建第三张表名字是h2g并且让这两张表有关联
    # h2g=models.ManyToManyField('Group')

class Group(models.Model):
    gid=models.AutoField(primary_key=True)
    name=models.CharField(max_length=16)
    h2g=models.ManyToManyField('Host')  #生成第三张表名字为Group_h2g

然后执行makemigrations ,migrate创建数据库表

 

 

如果要在第三张表中加入数据,就必须要用到through并且再创建第三章表

class HoseToGroup(models.Model):
    hgid=models.AutoField(primary_key=True)
    host_id=models.ForeignKey('Host')
    group_id=models.ForeignKey('Group')
    status=models.IntegerField()

class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32)
    ip=models.CharField(max_length=32)
    #在这个表或者下个表方法中用ManyToManyField就是创建第三张表名字是h2g并且让这两张表有关联
    # h2g=models.ManyToManyField('Group')

class Group(models.Model):
    gid=models.AutoField(primary_key=True)
    name=models.CharField(max_length=16)
    #如果要在第三张表中加入数据的时候必须后面加上through并且再加上一张表
    h2g=models.ManyToManyField('Host',through='HoseToGroup')
View Code

 

 

实战:

创建两张表和创建三张表的区别:

创建两张表,分别是主机和组

class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32)
    ip=models.CharField(max_length=32)
class Group(models.Model):
    gid=models.AutoField(primary_key=True)
    name=models.CharField(max_length=32)

    h2g=models.ManyToManyField('Host')
models文件

 

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r"^index/",views.index)
]
urls

 

##########################多对多############################
    #Host插入数据
    models.Host.objects.create(hostname='c1',ip='1.1.1.1')
    models.Host.objects.create(hostname='c2',ip='1.1.1.2')
    models.Host.objects.create(hostname='c3',ip='1.1.1.3')
    models.Host.objects.create(hostname='c4',ip='1.1.1.4')
    models.Host.objects.create(hostname='c5',ip='1.1.1.5')
    #Group插入数据
    models.Group.objects.create(name='财务部')
    models.Group.objects.create(name='人事部')
    models.Group.objects.create(name='公关部')
    models.Group.objects.create(name='技术部')
    models.Group.objects.create(name='运营部')
    models.Group.objects.create(name='销售部')
    models.Group.objects.create(name='客服部')
    '''将多台机器分配给一组【财务部】
    #创建财务部对象
    obj=models.Group.objects.get(gid=1)
    print(obj.h2g.all())#这里 为[] 空列表
    #获取Host中所有数据
    q=models.Host.objects.filter(hid__gt=0)
    #把Host所有数据加入到第三张表中
    obj.h2g.add(*q)
    '''
    """将一台机器分给多个组"""
    h=models.Host.objects.get(hid=1)
    # h.hostname,h.hid,h.group_set ,这里group_set与另一张表产生联系,这里的group_set是Host表中自动添加的
    #group_set.all()获取另一张表的所有信息,_gt是大于
    h.group_set.add(*models.Group.objects.filter(gid__gt=2))

    return HttpResponse("ok")
views文件

1、上面分别往两个数据库中加入数据

2、然后让这两张表产生联系,然后执行下面方法(queryset)

         a、将多台机器分配给一个组

         b、将一台机器分给多个组(注意这里用到了grounp_Set反向查找的方式)

 

其他方法:

#只移除关系表中的元素,这里移除group表中的元素
h.group_set.remove(*models.Group.objects.filter(gid__gt=3))
#这里queryset方式的删除不仅仅是删除第三张表内容还会删除关系表group表中的内容
h.group_set.all().delete()
#这里是如果第三张表中有gid大于3的内容就保留,其余的全部删,通过set方法看源码还有其他方法
h.group_set.set(models.Group.objects.filter(gid__gt=3))
View Code

 

创建三张表的实战:

class HoseToGroup(models.Model):
    hgid=models.AutoField(primary_key=True)
    host_id=models.ForeignKey('Host')
    group_id=models.ForeignKey('Group')
    status=models.IntegerField()

class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32)
    ip=models.CharField(max_length=32)
    #在这个表或者下个表方法中用ManyToManyField就是创建第三张表名字是h2g并且让这两张表有关联
    # h2g=models.ManyToManyField('Group')

class Group(models.Model):
    gid=models.AutoField(primary_key=True)
    name=models.CharField(max_length=16)
    #如果要在第三张表中加入数据的时候必须后面加上through并且再加上一张表
    h2g=models.ManyToManyField('Host',through='HoseToGroup')

然后views操作

 第三章表添加内容直接添加就可以

 models.HoseToGroup.objects.create(host_id=1,group_id=2,status=1) 不需要用set、add等如果用了会报错 

 总结:

 

多对多操作

创建表:

直接使用ManyToManyField方法  默认生成第三张表

自己定义第三张表

自己定义第三张表+ManyToManyField+through

操作:

默认生成第三张表

         直接使用ManyToManyField方法

         ---获取值

         add添加

         remove删除、filter.delete()

         set设置(添加、删除)

         get_or_create

         update_or_create

 

补充:

这里add方法的时候也可以传入列表或者具体的数字

如:models文件

from django.db import models

# Create your models here.
class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32)
    ip=models.CharField(max_length=32)
class Group(models.Model):
    gid=models.AutoField(primary_key=True)
    name=models.CharField(max_length=32)

    h2g=models.ManyToManyField('Host')
View Code
from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
def index(request):
    #Host插入数据
    models.Host.objects.create(hostname='c1',ip='1.1.1.1')
    models.Host.objects.create(hostname='c2',ip='1.1.1.2')
    models.Host.objects.create(hostname='c3',ip='1.1.1.3')
    models.Host.objects.create(hostname='c4',ip='1.1.1.4')
    models.Host.objects.create(hostname='c5',ip='1.1.1.5')
    #Group插入数据
    models.Group.objects.create(name='财务部')
    models.Group.objects.create(name='人事部')
    models.Group.objects.create(name='公关部')
    models.Group.objects.create(name='技术部')
    models.Group.objects.create(name='运营部')
    models.Group.objects.create(name='销售部')
    models.Group.objects.create(name='客服部')
    '''一个电脑对应多个组'''
    #这里只能用get方法
    h=models.Host.objects.get(hid=1)
    h.group_set.add(1)
    h.group_set.add(*[2.3])
    return HttpResponse("ok")
views文件

这里就能把1,2,3组传入到jango自己创建的第三章表中,对应第一个主机

 

 

 

 

自己定义第三张表+ManyToManyField+through

         --获取值  可以用filter,all等方法不能用add等方法

f和q操作数据库

补充group by
# group by
        #
        # from django.db.models import Count, Min, Max, Sum
        # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
        # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))  
表示取出c1=1这一列中的id中的所有的num为一组中的 num个数
F和q操作查询
# F 使用查询条件的值,专门取对象中某列值的操作(只对数据操作)

    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num')+1)
# Q 构建搜索条件
    from django.db.models import Q

    #1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询
    q1=models.Book.objects.filter(Q(title__startswith='P')).all()
    print(q1)#[<Book: Python>, <Book: Perl>]

    # 2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。
    Q(title__startswith='P') | Q(title__startswith='J')

    # 3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合  
    Q(title__startswith='P') | ~Q(pub_date__year=2005)

    # 4、应用范围:

    # Each lookup function that takes keyword-arguments (e.g. filter(),
    #  exclude(), get()) can also be passed one or more Q objects as
    # positional (not-named) arguments. If you provide multiple Q object
    # arguments to a lookup function, the arguments will be “AND”ed
    # together. For example:

    Book.objects.get(
        Q(title__startswith='P'),
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
    )

    #sql:
    # SELECT * from polls WHERE question LIKE 'P%'
    #     AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

    # import datetime
    # e=datetime.date(2005,5,6)  #2005-05-06

    # 5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。
    # 正确:
    Book.objects.get(
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
        title__startswith='P')
    # 错误:
    Book.objects.get(
        question__startswith='P',
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))


filter:只能进行单表查询
q:其实就是封装查询
& and  | or  ~ not

  

 

posted @ 2017-05-19 22:42  pyrene  阅读(693)  评论(0编辑  收藏  举报