zoukankan      html  css  js  c++  java
  • django orm

    models.py:

    from django.db import models
    
    # Create your models here.
    
    class Publisher(models.Model):
        name = models.CharField(max_length=255, verbose_name='出版社')
        address = models.CharField(max_length=255, verbose_name='地址')
    
        class Meta:
            verbose_name = '出版社'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    class Athor(models.Model):
        name = models.CharField(max_length=50, unique=True, verbose_name='作者')
        age = models.SmallIntegerField(verbose_name='年龄')
        choices = ((1, ''), (2, ''))
        sex = models.SmallIntegerField(choices=choices, default=1)
    
        class Meta:
            verbose_name = '作者'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    class Book(models.Model):
        name = models.CharField(max_length=64, unique=True, verbose_name='书名')
        athor = models.ManyToManyField(Athor, verbose_name='作者')
        publisher = models.ForeignKey(Publisher, verbose_name='发行出版社')
    
        class Meta:
            verbose_name = '书籍'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name

    查询所有书籍:

    >>> books = models.Book.objects.all()
    >>> for book in books:
    ...     print(book.name)
    ... 
    三国演义
    西游记
    水浒传
    红楼梦
    陆小凤传奇
    三少爷的剑
    >>>

    查询‘三国演义’这本书:

    >>> books = models.Book.objects.get(name='三国演义')
    >>> books.name
    '三国演义'
    
    #要注意的是,get方法如果要查询的书不存在的话,会抛出错误
    >>> book2 = models.Book.objects.get(name='四国演义')
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/home/huangxm/.pyenv/versions/django196/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
        return getattr(self.get_queryset(), name)(*args, **kwargs)
      File "/home/huangxm/.pyenv/versions/django196/lib/python3.5/site-packages/django/db/models/query.py", line 385, in get
        self.model._meta.object_name
    book.models.DoesNotExist: Book matching query does not exist.
    
    #这种情况可以用filter来查询
    >>> book2 = models.Book.objects.filter(name='四国演义')
    >>> book2
    <QuerySet []>
    >>> for book in book2:
    ...     print(book.name)
    ... 
    >>> 
    #结果为空,表示没有查询到
    查找第一条和最后一条数据:
    >>> book = models.Book.objects.last()
    >>> book.name
    '三少爷的剑'
    >>> book = models.Book.objects.first()
    >>> book.name
    '三国演义'
    >>>

    filter:

    #多条件查找
    >>> book = models.Publisher.objects.filter(name='人民邮电出版社', address='人民路')
    
    #模糊查询,__连接
    >>> book = models.Publisher.objects.filter(address__contains='')
    >>> for i in book:
    ...     print(i.name, i.address)
    ... 
    电子工业出版社 工业路
    人民邮电出版社 人民路
    机械工业出版社 机械路
    
    #模糊查询,忽略大小写
    >>> book = models.PUblisher.objects.filter(address__icontains='Zeng')
    
    #查询年龄在列表中的人
    >>> athor = models.Athor.objects.filter(age__range=[99,99999])
    >>> for i in athor:
    ...     print(i.name)
    ... 
    吴承恩
    施耐庵
    罗贯中
    曹雪芹
    高鹗
    薜兴国
    古龙
    
    #startswith, endswith, istartswith, iendswith
    >>> publisher = models.Publisher.objects.filter(address__startswith='')
    >>> for i in publisher:
    ...     print(i.name)
    ... 
    人民邮电出版社

     

    添加数据:

    #添加出版社
    new_publisher = models.Publisher(name='阳光出版社', address='阳光路")
    new_publisher.save()
    
    #使用create添加,这种方式不需要save()
    models.Publisher.objects.create(name='阳光出版社', address=‘阳光路’)

    批量修改数据:

    #修改id为1,2,3的作者性别,update方法不需要save(),而且效率比较高
    >>> models.Athor.objects.filter(id__range=[1,3]).update(sex=2)
    3
    >>> athor_obj = models.Athor.objects.filter(id__range=[1,3])
    >>> for i in athor_obj:
    ...     print(i.id, i.name, i.sex)
    ... 
    1 网络写手one 2
    2 言情写手 2
    3 玄幻写手 2

    连锁查询:

    #查询所有作者,并按年龄排序,如果想倒着排序order_by('-age')
    >>> p = models.Athor.objects.all().order_by('age')
    >>> for i in p:
    ...     print(i.name, i.age)
    ... 
    薜兴国 99
    古龙 99
    吴承恩 99999
    施耐庵 99999
    罗贯中 99999
    曹雪芹 99999
    高鹗 99999
    
    #对查询结果计数
    >>> models.Publisher.objects.filter(address__endswith='').count()
    3

    外键(一对多)查询:

    从具有ForeignKey的表查询称为正向查询,反过查称为反向查询

    正向查询:

    >>> obj = models.Book.objects.filter(publisher__name='电子工业出版社')
    >>> for i in obj:
    ...     print(i.name)
    ... 
    三国演义
    陆小凤传奇
    三少爷的剑
    
    
    #查询书的出版社
    >>> obj = models.Book.objects.filter(name='西游记')
    >>> for i in obj:
    ...     print(i.publisher)
    ... 
    人民邮电出版社

    反向查询,从出版社查书

    #查询id为3的出版社出版的书
    >>> obj = models.Publisher.objects.get(id=3)
    >>> books = obj.book_set.all()
    >>> for book in books:
    ...     print(book.name, book.publisher)
    ... 
    水浒传 机械工业出版社
    红楼梦 机械工业出版社

     

    一对多添加数据:

    #通过外键字段的ID进行添加
    >>> models.Book.objects.create(name='长篇小说', publisher_id=1)
    <Book: 长篇小说>
    
    #字典形式
    >>> dic = {'name': '短篇小说', 'publisher_id':2}
    >>> models.Book.objects.create(**dic)
    <Book: 短篇小说>
    
    
    #通过对象添加
    >>> publisher_obj = models.Publisher.objects.filter(name='阳光出版社')
    >>> models.Book.objects.create(name='小小说', publisher=publisher_obj[0])
    <Book: 小小说>

    多对多查询:

    一本书可以有多个作者,一个作者可以写很多书

    #查询书的所有作者
    >>> b1 = models.Book.objects.get(name='陆小凤传奇')
    >>> a = b1.athor.select_related()
    >>> for i in a:
    ...     print(i, i.name, i.age)
    ... 
    薜兴国  薜兴国  99
    古龙  古龙   99

     

    多对多添加数据:

    正向添加数据:当我们要添加一本书籍的时候,先正常添加作者和书籍,然后我们找到这些书籍和作者,再为书籍添加作者

    #添加一本新书
    >>> models.Book.objects.create(name='新书籍', publisher_id=1)
    <Book: 新书籍>
    #找到这本书
    >>> book_obj = models.Book.objects.get(name='新书籍')
    #找出作者们
    >>> athor_obj = models.Athor.objects.filter(id__range=[1,3])
    #为书籍添加这些作者
    >>> book_obj = models.Book.objects.get(name='新书籍')
    >>> book_obj.athor.add(*athor_obj)

    反向添加数据:获取书籍,获取作者,为作者添加书籍

    >>> book_obj = models.Book.objects.get(name='新书籍')
    >>> athor_obj = models.Athor.object.filter(id_range[1,3])
    >>> athor_obj.book_set.add(*book_obj)

     

    自定义多对多中间表:

    在多对多关系中,Django会自动创建多对多的中间表,中间表中两个外键字段,分别关联到多对多的两张表中;但大多数情况下,我们需要手动创建中间表,因为我们可能需要在中间表中添加其它字段;

    那我们如何来自定义中间表呢?修改一下models.py 中的book, 再定义AthorRelation表:

    class Book(models.Model):
        name = models.CharField(max_length=64, unique=True, verbose_name='书名')
        #如果要使用自定义第三张表那么需要throught来定义第三张表名
        athor = models.ManyToManyField(Athor, verbose_name='作者', through='AthorRelation')
        publisher = models.ForeignKey(Publisher, verbose_name='发行出版社')
    
        class Meta:
            verbose_name = '书籍'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    #自定义多对多的第三张表
    class AthorRelation(models.Model):
        athor = models.ForeignKey(Athor)
        book = models.ForeignKey(Book)
    
        class Meta:
            verbose_name = '书籍作者对应关系表'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.book.name

    查询有两种方法:

    第一种:

    #正向查,从manytomany字段所在表查起
    >>> book_obj = models.Book.objects.get(name='青云志')
    >>> for i in book_obj.athor.all():
    ...     print(i)
    ... 
    玄幻写手
    言情写手
    #反向查
    >>> athor_obj = models.Athor.objects.get(name='玄幻写手')
    >>> athor_obj.book_set.all()
    <QuerySet [<Book: 青云志>]>
    >>> for i in athor_obj.book_set.all():
    ...     print(i)
    ... 
    青云志

    第二种方法:比较简单,直接从中间表下手:

    >>> rel = models.AthorRelation.objects.all()
    >>> for i in rel:
    ...     print(i.athor.name, i.book.name)
    ... 
    玄幻写手 青云志
    言情写手 青云志
    
    #使用filter
    >>> rel = models.AthorRelation.objects.filter(book__name='青云志')
    >>> for i in rel:
    ...     print(i.book.name, i.athor.name)
    ... 
    青云志 玄幻写手
    青云志 言情写手

    添加数据:

    当我们使用了自定义的中间表时,多对多添加数据的add方法就不能使用了,我们可以直接操作第三张表来添加数据,更加简单直接:

    1. 通过对象添加, 笨方法

    >>> models.AthorRelation.objects.create(
                  athor=models.Athor.objects.get(id=3),
                  book=models.Book.objects.get(id=2)
    )

    2. 通过ID来添加,比较简洁

    >>> models.AthorRelation.objects.create(athor_id=2, book_id=2)
    <AthorRelation: 长篇小说>

    删除数据:

    先查询一下:

    >>> obj = models.AthorRelation.objects.all()
    >>> for i in obj:
    ...     print(i.book.name, i.athor.name)
    ... 
    长篇小说 玄幻写手
    长篇小说 言情写手
    小小说 玄幻写手
    小小说 灵异写手

    删除一个作者:

    >>> obj=models.AthorRelation.objects.all()
    >>> obj
    <QuerySet [<AthorRelation: 长篇小说>, <AthorRelation: 小小说>]>
    >>> for i in obj:
    ...     print(i.book.name, i.athor.name)
    ... 
    长篇小说 言情写手
    小小说 灵异写手

    删除书籍长篇小说:

    >>> book_obj = models.Book.objects.get(name='长篇小说')
    >>> book_obj.delete()
    (2, {'book.Book': 1, 'book.AthorRelation': 1})
    >>> rel = models.AthorRelation.objects.all()
    >>> for i in rel:
    ...     print(i.book.name, i.athor.name)
    ...
    可以看出:当我们删除一条记录时,中间表中对应的记录也会被删除。
  • 相关阅读:
    Xshell配置ssh免密码登录-密钥公钥(Public key)与私钥(Private Key)登录
    bypass disable_function的方法及蚁剑插件bypass-php-function使用
    cisco-GNS3-pix防火墙基本配置实操(持续更新)
    "锁定文件失败 打不开磁盘或它所依赖的某个快照磁盘。模块启动失败。未能启动虚拟机"--解决方法
    python实现图片转字符画
    GNS3--cisco路由器NAT配置
    python虚拟环境----virtualenv
    防火墙----思科路由器基本配置1
    XXE漏洞学习1
    vc程序设计-----位图
  • 原文地址:https://www.cnblogs.com/huangxm/p/5787604.html
Copyright © 2011-2022 走看看