zoukankan      html  css  js  c++  java
  • Django之model

    一.创建表

    django中ORM和数据库的映射关系:

                表名  <-------> 类名

                字段  <-------> 属性

       表记录 <------->类实例对象

    创建表就是一个创建类的过程:

    class Book(models.Model):
        nid=models.AutoField(primary_key=True)
        title=models.CharField(max_length=32)
        publishDate=models.DateField()
        price=models.DecimalField(max_digits=5,decimal_places=3)
        python manage.py makemigrations
        python manage.py migrate

     外键,一对一,多对多:

    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32)
        age=models.IntegerField()
     
        # 与AuthorDetail建立一对一的关系
        authorDetail=models.OneToOneField(to="AuthorDetail")
     
    class AuthorDetail(models.Model):
     
        nid = models.AutoField(primary_key=True)
        birthday=models.DateField()
        telephone=models.BigIntegerField()
        addr=models.CharField( max_length=64)
    
    class Publish(models.Model):
        nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32)
        city=models.CharField( max_length=32)
        email=models.EmailField()
    
    class Book(models.Model):
        nid = models.AutoField(primary_key=True)
        title = models.CharField( max_length=32)
        publishDate=models.DateField()
        price=models.DecimalField(max_digits=5,decimal_places=2)
    #upload_to文件保存的位置  默认放在文件的根文件夹,如果加了media配置则media/下面
    avatar=models.FileField(upload_to='avatars/',default='static/img/avatars/default.png'
    # 与Publish建立一对多的关系,外键字段建立在多的一方 
    #through是值定关联表
    tags = models.ManyToManyField(
    to="Tag",
    through='Article2Tag',
    through_fields=('article', 'tag'),
    )

    publish
    =models.ForeignKey(to="Publish",to_field="nid") # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to='Author')
    #联合唯一
    class Meta:
    unique_together = [
    ('article', 'user'),
    ]
    '''
    注意事项:  
    1、id 字段是自动添加的
    2、对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
    3、这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
    4、定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
    5、外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
    
    '''

     都有哪些字段:

    CharField    字符串
    IntegerField   整型

    字段属性:

    max_length     最大长度 (CharField必须加)
    choice=((1,''),(2,''))         相当于枚举

    二.添加记录

    #单表添加
    #方式一:
    publish_obj=Publish.objects.create(name="人民出版社",
        city="北京",email="renMin@163.com")
    #方式二:
    publish_obj=Publish(name="人民出版社",city="北京",email="renMin@163.com")
    publish_obj.save()
    #方式三:
    Publish.objects.create(**request.POST.dict())
    #带外键添加:
    #一:
    Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=665,       pagegeNum= 334,publish_id=1)
    #二:
    publish_obj=Publish.objects.get(nid=1)
    Book.objects.create(title="金瓶眉",publishDate="2012-12-12", price=665,pageNum=334,publish=publish_obj)     
    #多对多添加
    book_obj=Book.objects.create(title="追风筝的人",publishDate="2012-11-12",price=69,pageNum=314,publish_id=1)
     
    author_yuan=Author.objects.create(name="yuan",age=23,authorDetail_id=1)
    author_egon=Author.objects.create(name="egon",age=32,authorDetail_id=2)
     
    book_obj.authors.add(author_egon,author_yuan)    
    '''将某个特定的 model 对象添加到被关联对象集合中。   =======    book_obj.authors.add(*[])
    '''
    
    #接触关系
    book_obj.authors.remove()     # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
    book_obj.authors.clear()       #清空被关联对象集合。

     批量添加数据:

    book_list=[]
    for i in range(500):
        book_obj=Book(title='book%s'%i,price=i)
        book_list.append(book_obj)
    Book.objects.bulk_create(book_list)

    三.查询记录

    3.1 查询相关API

    <1> all():                 查询所有结果
     
    <2> filter(**kwargs):      它包含了与所给筛选条件相匹配的对象
     
    <3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
                               如果符合筛选条件的对象超过一个或者没有都会抛出错误。
     
    <5> exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象
     
    <4> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                               model的实例化对象,而是一个可迭代的字典序列
     
    <9> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
     
    <6> order_by(*field):      对查询结果排序
     
    <7> reverse():             对查询结果反向排序
     
    <8> distinct():            从返回结果中剔除重复纪录
     
    <10> count():              返回数据库中匹配查询(QuerySet)的对象数量。
     
    <11> first():              返回第一条记录
     
    <12> last():               返回最后一条记录
     
    <13> 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

    3.2 基于对象的跨表查询(子查询)

    3.2.1 正向查询(按字段)

    #一对多
    # 查询nid=1的书籍的出版社所在的城市<br>
    book_obj=Book.objects.get(nid=1)
    print(book_obj.publish.city)
    #一对一
    author_egon=Author.objects.get(name="egon")
        print(author_egon.authorDetail.telephone)
    #多对多
    # 金瓶眉所有作者的名字以及手机号
     
        book_obj=Book.objects.filter(title="金瓶眉").first()
     
        authors=book_obj.authors.all()
     
        for author_obj in authors:
     
            print(author_obj.name,author_obj.authorDetail.telephone)

    3.2.2 反向查询

    #一对多
    #表名小写+'_'+'set'
    
    book_list=Publish.objects.filter(name='人民出版社').first().book_set.all()
    print(book_list)
    #一对一
    #表名小写
    #住在天堂的作者的名字
    author_obj=AuthorDetail.objects.filter(addr='天堂').author
    print(author_obj.name)
    #多对多
    #表名小写_set
    # 查询egon出过的所有书籍的名字
    book_objs=Author.objects.filter(name='egon').first().book_set.all()
    for book_obj in book_objs:
       print(book_obj,book_obj.title)

     

    3.3 基于双下划线的跨表查询(join查询)

    注意:正向查询按字段,反向查询按表名

    # 练习1:  查询人民出版社出版过的所有书籍的名字与价格(一对多)
    
        # 正向查询 按字段:publish
    
        queryResult=Book.objects
                .filter(publish__name="人民出版社")
                .values_list("title","price")
    
        # 反向查询 按表名:book
    
        queryResult=Publish.objects
                  .filter(name="人民出版社")
                  .values_list("book__title","book__price")
    
    
    
    # 练习2: 查询egon出过的所有书籍的名字(多对多)
    
        # 正向查询 按字段:authors:
        queryResult=Book.objects
                .filter(authors__name="yuan")
                .values_list("title")
    
        # 反向查询 按表名:book
        queryResult=Author.objects
                  .filter(name="yuan")
                  .values_list("book__title","book__price")
    
    
    # 练习3: 查询人民出版社出版过的所有书籍的名字以及作者的姓名
    
    
        # 正向查询
        queryResult=Book.objects
                .filter(publish__name="人民出版社")
                .values_list("title","authors__name")
        # 反向查询
        queryResult=Publish.objects
                  .filter(name="人民出版社")
                  .values_list("book__title","book__authors__age","book__authors__name")
    
    
    # 练习4: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称
    
        queryResult=Book.objects
                .filter(authors__authorDetail__telephone__regex="151")
                .values_list("title","publish__name"

    3.4 聚合参数与分组查询

    #聚会:aggregate(*args,**kwargs)
    >>> Book.objects.all().aggregate(Avg('price'))
        {'price__avg': 34.35}
    #aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。
    #可以向aggregate()子句中添加多个参数
    >>> from django.db.models import Avg, Max, Min
    >>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
    {'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
    #分组 annotate()
    
    bookList=Book.objects.annotate(authorsNum=Count('authors'))
    for book_obj in bookList:
        print(book_obj.title,book_obj.authorsNum)

    3.5 F Q查询

    F查询

    Django 提供 F() 来对两个字段的值做比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。 

    # 查询评论数大于收藏数的书籍
    from django.db.models import F
    Book.objects.filter(commnetNum__lt=F('keepNum'))

    Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

    # 查询评论数大于收藏数2倍的书籍
    Book.objects.filter(commnetNum__lt=F('keepNum')*2)

    Q查询

    可以利用& ,|,~三个符号进行与或非的逻辑运算

    bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))
    bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")
    bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),title__icontains="python")

    四.修改和删除

    修改:

    update()

    删除:

    delete()

    在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象

    '''
    delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用
    '''
    Entry.objects.all().delete()
    #不想级联删除,可以设置为
    pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)

    五. models的一些其他用法

    http://www.cnblogs.com/hantaozi430/articles/8571378.html

  • 相关阅读:
    React Children 使用
    Redux 中间件和异步操作
    Redux 核心概念
    React 的setState 异步理解
    JS 中类型和类型转换
    ES6 新增集合----- Set 和Map
    ES6 新增基本数据类型Symbol
    ES6 解构赋值
    ES6 对象增强
    ES6 中的let 和 const
  • 原文地址:https://www.cnblogs.com/hantaozi430/p/8350526.html
Copyright © 2011-2022 走看看