zoukankan      html  css  js  c++  java
  • django orm

     orm字段及参数

    orm字段

    1. null
    2. default
    3. unique
    4. db_index
    
    5. DateField和DateTimeField才有的参数:
    	auto_now_add=True     --> 创建数据的时候自动把当前时间赋值
    	auto_add=True         --> 每次更新数据的时候更新当前时间
    	
    	上述两个不能同时设置!!!
    
    5. class Meta:
    	 db_table = "表名"
    

      

    创建表

    索引

    联合唯一

    class Meta:
            # 建立联合唯一约束
        unique_together = ("author", "book")
    View Code

    一对一

    # 作者
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        phone = models.IntegerField()
        books = models.ManyToManyField(to="Book", related_name="authors")
        detail = models.OneToOneField(to="AuthorDetail")
    
        def __str__(self):
            return self.name
    
    
    # 作者详情
    class AuthorDetail(models.Model):
        # 爱好
        hobby = models.CharField(max_length=32)
        # 地址
        addr = models.CharField(max_length=128)
    View Code

    一对多

    使用外键:

    class Book(models.Model):
        id=models.AutoField(primary_key=True)
        title=models.CharField(max_length=64,unique=True)
        price = models.DecimalField(max_digits=5, decimal_places=2, default=99.99)
        publisher=models.ForeignKey(
            to="Publisher",
            related_name='books',#用于外键反向查询,代替book__set,添加后book_set将不能用。
            related_query_name="xxoo",#用于双下方法查询
            on_delete=True,
        )
    
        def __str__(self):
            return "<Book Object:{}>".format(self.title)
    View Code

     关联表内字段

    class Comment(models.Model):
        """
        评论表
        """
        nid=models.AutoField(primary_key=True)
        article=models.ForeignKey(to="Article",to_field="nid")
        user=models.ForeignKey(to="UserInfo",to_field="nid")
        content=models.CharField(max_length=255)
        create_time=models.DateTimeField(auto_now_add=True)
        parent_comment=models.ForeignKey("self",null=True)
    View Code

    多对多

    方式一:自动生成,第三张表

    #
    class Book(models.Model):
        id=models.AutoField(primary_key=True)
        title=models.CharField(max_length=64,unique=True)
        price = models.DecimalField(max_digits=5, decimal_places=2, default=99.99)
        publisher=models.ForeignKey(
            to="Publisher",
            related_name='books',#用于外键反向查询,代替book__set,添加后book_set将不能用。
            related_query_name="xxoo",#用于双下方法查询
            on_delete=True,
        )
    
        def __str__(self):
            return "<Book Object:{}>".format(self.title)
    
    #作者
    class Author(models.Model):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=16,unique=True)
        book=models.ManyToManyField(to="Book")
        def __str__(self):
            return "<Author Object:{}>".format(self.name)
    View Code

    方式二:手动创建第三张表

    # 出版社
    class Publisher(models.Model):
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    
    #
    class Book(models.Model):
        title = models.CharField(max_length=32)
        publish_date = models.DateField(auto_now_add=True)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        # 创建外键,关联publish
        publisher = models.ForeignKey(to="Publisher")
    
        def __str__(self):
            return self.title
    
    
    # 作者
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        phone = models.IntegerField()
        books = models.ManyToManyField(to="Book", related_name="authors")
        detail = models.OneToOneField(to="AuthorDetail")
    
        def __str__(self):
            return self.name
    
    
    # 作者详情
    class AuthorDetail(models.Model):
        # 爱好
        hobby = models.CharField(max_length=32)
        # 地址
        addr = models.CharField(max_length=128)
    View Code

    方式三:指定关联创建

    class Book(models.Model):
        title = models.CharField(max_length=32, verbose_name="书名")
    
    
    # 自己创建第三张表,并通过ManyToManyField指定关联
    class Author(models.Model):
        name = models.CharField(max_length=32, verbose_name="作者姓名")
        books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book"))
        # through_fields接受一个2元组('field1','field2'):
        # 其中field1是定义ManyToManyField的模型外键的名(author),field2是关联目标模型(book)的外键名。
    
    
    class Author2Book(models.Model):
        author = models.ForeignKey(to="Author")
        book = models.ForeignKey(to="Book")
    
        class Meta:
            unique_together = ("author", "book")
    View Code

    orm操作

    查询

    查询示例

    model1

    from django.db import models
    
    # Create your models here.
    '''
    图书馆里系统
    '''
    #出版社
    class Publisher(models.Model):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=64,unique=True)
        addr=models.CharField(max_length=128)
        def __str__(self):
            return "<Publisher Object:{}>".format(self.name)
    
    #
    class Book(models.Model):
        id=models.AutoField(primary_key=True)
        title=models.CharField(max_length=64,unique=True)
        publish_date = models.DateField(verbose_name='出版日期',auto_now_add=True,null=True,blank=True)
        # 库存数
        kucun = models.IntegerField(default=1000)
        # 卖出数
        maichu = models.IntegerField(default=0)
        price = models.DecimalField(max_digits=5, decimal_places=2, default=99.99)
        publisher=models.ForeignKey(
            to="Publisher",
            related_name='books',#用于外键反向查询,代替book__set,添加后book_set将不能用。
            related_query_name="xxoo",#用于双下方法查询
            on_delete=True,
        )
    
        def __str__(self):
            return "<Book Object:{}>".format(self.title)
    
    #作者
    class Author(models.Model):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=16,unique=True)
        book=models.ManyToManyField(to="Book")
        detail=models.OneToOneField(verbose_name="用户详情",to="AuthorDetail",on_delete=models.CASCADE,null=True,blank=True)
        def __str__(self):
            return "<Author Object:{}>".format(self.name)
    
    
    class Person(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField(default=18)
        birthday = models.DateField(auto_now_add=True)
    
        def __str__(self):
            return "<Person Object:{}>".format(self.name)
    
    #作者详情
    class AuthorDetail(models.Model):
        hobby=models.CharField(verbose_name='爱好',max_length=32,null=True)
        addr=models.CharField(verbose_name='地址',max_length=128,null=True)
    
    #手动创建第三张表
    # class Author2Book(models.Model):
    #     id = models.AutoField(primary_key=True)
    #     # 作者id
    #     author = models.ForeignKey(to="Author")
    #     # 书id
    #     book = models.ForeignKey(to="Book")
    #
    #     class Meta:
    #         # 建立联合唯一约束
    #         unique_together = ("author", "book")
    View Code

    orm1

    """
    ORM小练习
    
    如何在一个Python脚本或文件中 加载Django项目的配置和变量信息
    """
    import os
    if __name__ == '__main__':
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dnp.settings')
        import django
        django.setup()
        from app01 import models
        #查询所有
        # ret=models.Person.objects.all()
        # print(ret)
        #get查询(不存在会报错)
        # ret2=models.Person.objects.get(name='李世民1')
        # print(ret2)
        #filter
        # ret3=models.Person.objects.filter(id=1)
        # print(ret3)
        #查询结果只有一个也返回queryset
        # ret4=models.Person.objects.filter(id=1)[0]
        # print(ret4)
        # print("exclude".center(80, "*"))
        # #查询除了id=1的
        # ret5=models.Person.objects.exclude(id=1)
        # print(ret5)
        #只查询指定字段,里面是字典
        # ret6=models.Person.objects.values('name','birthday')
        # print(ret6)
        # 只查询指定字段,里面是元祖
        # ret7=models.Person.objects.values_list('name','birthday')
        # print(ret7)
        #字段排序
        # ret8 = models.Person.objects.order_by('birthday')
        # print(ret8)
        #将有序的Querysset进行反转
        # ret9 = models.Person.objects.order_by('id').reverse()
        # print(ret9)
        #返回queryset中对象的数量
        # ret10=models.Person.objects.count()
        # print(ret10)
        #返回QuerySet中第一个对象
        # ret11=models.Person.objects.first()
        # print(ret11)
        #返回QuerySet中最后一个对象
        # ret12=models.Person.objects.last()
        # print(ret12)
        #判断表中有没有数据
        # ret13=models.Person.objects.exists()
        # print(ret13)
        #
    
    
        # 单表查询双下划线
        #查询id大于1小于4的内容
        # r1=models.Person.objects.filter(id__gt=1,id__lt=4)
        # print(r1)
        #查询id在[1,3,5,7]中的结果
        # r2=models.Person.objects.filter(id__in=[1,3,5,7])
        # print(r2)
        #查询id不在[1,3,5,7]中的数据
        # r3 = models.Person.objects.exclude(id__in=[1, 3, 5, 7])
        # print(r3)
        #查询名字中包含李的字段
        # r4=models.Person.objects.filter(name__contains='李')
        # print(r4)
        # # icontains 忽略大小写包含指定值
        # r5=models.Person.objects.filter(name__icontains='C')
        # print(r5)
        # # range
        # # 判断id值在 哪个区间的 SQL语句中的between and  1<= <=3
        # r6=models.Person.objects.filter(id__range=[1,3])
        # print(r6)
        #日期和时间字段查询
        # r7=models.Person.objects.filter(birthday__year='2018')
        # print(r7)
        # r8 = models.Person.objects.filter(birthday__year=2018, birthday__month=10)
        # print(r8)
    
        #外键查询
        #正向查询
        #基于对象跨表查询
        # book_obj = models.Book.objects.all().first()
        # f1 = book_obj.publisher  # 和我这本书关联的出版社对象
        # print(f1, type(f1))
        # f2=book_obj.publisher.name
        # print(f2)
        #查询id为1的书的出版社
        #使用双下方法进行跨表查询
        # f3=models.Book.objects.filter(id=2).values_list('price','publisher__name')
        # print(f3)
        #反向查询,
        #1.基于对象查询
        #publisher_obj=models.Publisher.objects.get(id=1)
        # f4= publisher_obj.book_set.all()
        # print(f4)
        #配置related_name='books'后book_set将不再可用。
        # f5= publisher_obj.books.all()
        # print(f5)
        #2.基于双下方法
        #添加related_query_name="xxoo",#用于双下方法查询
        # f5=models.Publisher.objects.filter(id=1).values_list('xxoo__title')
        # print(f5)
    
        #多对多
        # 查询
        # author_obj=models.Author.objects.all().first()
        # print(author_obj)
        # #查看所有书
        # f6=author_obj.book.all()
        # print(f6,type(f6))
        #通过作者添加一本书
        # author_obj = models.Author.objects.all().first()
        # author_obj.book.create(title='明朝那些事',publisher_id=2)
        #add()
        #给id为3的作者添加id为10的一本书,必须使用get()查
        #get获取的是类,filter,获取的是querySet()
        # author_obj=models.Author.objects.get(id=3)
        # book_obj=models.Book.objects.get(id=10)
        # author_obj.book.add(book_obj)
        #添加多个
        # book_objs=models.Book.objects.filter(id__gt=1)
        # print(book_objs)
        # author_obj.book.add(*book_objs)
        #直接添加id
        # author_obj.book.add(9)
        # 删除关联
        #把id为3的作者,的id为10的书取消关联
        # author_obj=models.Author.objects.get(id=3)
        # author_obj.book.remove(10)
        #也可以使用对象
        # book_obj=models.Book.objects.get(id=8)
        # author_obj.book.remove(book_obj)
    
        #clear
        #清除所有关联
        # author_obj=models.Author.objects.get(id=3)
        # author_obj.book.clear()
        # 使用反向关联
        # 找到id是1的出版社
        # publisher_obj = models.Publisher.objects.get(id=2)
        # publisher_obj.books.clear()
    
        #聚合
        from django.db.models import Avg,Max,Min,Count,Sum
        #获取所有书的平均价格
        # h1= models.Book.objects.all().aggregate(price_avg=Avg("price"))
        # print(h1)
        #平均,最大,最小价格
        # h2=models.Book.objects.all().aggregate(price_avg=Avg("price"),price_max=Max("price"),price_min=Min("price"))
        # print(h2)
    
        #分组查询
        #查询每本书对应作者数量
        # h3=models.Book.objects.all().annotate(author_num=Count("author"))
        # print(h3)
        # for book in h3:
        #     print('书名{},作者数量:{}'.format(book.title,book.author_num))
    
        #查询作者数量大于1的书
        # h4=models.Book.objects.all().annotate(author_num=Count("author")).filter(author_num__gt=1)
        # for book in h4:
        #     print('书名{},作者数量:{}'.format(book.title, book.author_num))
        #查询每个作者出的书的总价格
        # h5=models.Author.objects.all().annotate(price_sum=Sum("book__price")).values_list('name','price_sum')
        # for author in h5:
        #     print(author)
        # h6=models.Author.objects.all().annotate(price_sum=Sum("book__price"))
        # for i in h6:
        #     print(i,i.name,i.price_sum)
        #
        # print(h6.values_list("name","price_sum"))
    
    
        #F和Q
        from django.db.models import F
        #查出库存数大于卖出数的所有书】
        # f1=models.Book.objects.filter(kucun__gt=F("maichu"))
        # print(f1)
        # for i in f1:
        #     print(i.title,i.kucun,i.maichu)
            # print('库存{},卖出{}'.format(f1.kucun,f1.maichu))
        #把每一本书的卖出数乘3
        # book_obj=models.Book.objects.first()
        # book_obj.maichu=book_obj.maichu*3
        # book_obj.save()
        #
        # models.Book.objects.update(maichu=(F("maichu")+1)*3)
        #给每一本书名后面加上第一版
        from django.db.models.functions import Concat
        from django.db.models import Value
        # models.Book.objects.update(title=Concat(F("title"),Value("第一版")))
        from django.db.models import Q
        #查询卖出数大于1000,价格小于100的所有书
        # q1=models.Book.objects.filter(maichu__gt=1000,price__lt=100)
        # print(q1)
        #查询卖出数大于1000或价格小于100的所有书
        # q2=models.Book.objects.filter(Q(maichu__gt=1000)|Q(price__lt=100))
        # print(q2)
        #Q查询和字段查询同时存在的,字段查询要放在后面
        # q3=models.Book.objects.filter(Q(maichu__gt=1000)|Q(price__lt=100),title__contains='go')
        # print(q3)
    
        # Django ORM 事务
    
        # try:
        #     from django.db import transaction
        #     with transaction.atomic():
        #         # 创建一个出版社
        #         new_publisher = models.Publisher.objects.create(name="火星出版社", addr="火星路")
        #         # 创建一本书
        #         models.Book.objects.create(
        #             title='橘子物语',
        #             price=11.11,
        #             kucun=100,
        #             maichu=10,
        #             publisher_id=1000#指定一个不存在的出版社
        #         )
        # except Exception as e:
        #     print(str(e))
    
    
        #没有指定原子操作
        # try:
        #     #创建一个出版社
        #     new_publisher=models.Publisher.objects.create(title="火星出版社",addr="火星路")
        #     #创建一本书
        #     models.Book.objects.create(
        #         title='橘子物语',
        #         price=11.11,
        #         kucun=100,
        #         maichu=10,
        #         publisher_id=1000
        #     )
        # except Exception as e:
        #     print(str(e))
    
    
    
        #执行原生sql
        from django.db import connection
        # cursor=connection.cursor()
        # cursor.execute("select * from app01_book where id=%s",[2])
        # #多条查询
        # # ret=cursor.fetchall()
        # #单条查询
        # ret=cursor.fetchone()
        # print(ret)
    
        # 在QuerSet查询的基础上自己指定其他的SQL语句(了解即可)
    View Code

    orm2

    import sys,os
    
    
    if __name__ == '__main__':
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dnp.settings')
        import django
        django.setup()
        from app01 import models
        #一对一关联
        o1=models.Author.objects.first();
        print(o1.detail.hobby)
        #查询id为2作者关联的书
        # author_obj=models.Author.objects.get(id=2)
        # print(author_obj.book.all())
        #从作者2关联的书中移除id为2的书
        # models.Author.objects.get(id=2).book.remove(2)
        #在app01中,查询,作者id为1,的所有书的id,
        from app02 import models
        # o3=models.Author2Book.objects.filter(author_id=1).values_list('book_id')
        # ret=[i[0] for i in o3]
        # print(ret)
        # o4=models.Book.objects.filter(id__in=ret)
        # print(o4)
        #刪除关联
        # models.Author2Book.objects.get(book_id=1,author_id=1).delete()
    View Code

    orm3

    import sys,os
    
    
    if __name__ == '__main__':
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dnp.settings')
        import django
        django.setup()
        from app01 import models
        #查询名字里面包含go的书
        # q1=models.Book.objects.filter(title__contains='go')
        # print(q1)
        #查询2019年出版的书
        # q2=models.Book.objects.filter(publish_date__year=2019)
        # print(q2)
        #去重distinct()
        #查询所有书关联的出版社
        # q3=models.Book.objects.all().values_list("publisher__name")
        # print(q3.distinct())
        #把所有的书按照价格倒序排列
        # q4=models.Book.objects.all().order_by('price').reverse()
        #     # print(q4)
        #支持负号
        # q5=models.Book.objects.all().order_by('-price')
        # print(q5)
        #查询go法典的出版社城市
        # q6=models.Book.objects.filter(title='go法典').values_list("publisher__addr")
        # print(q6)
        #查询go法典作者的爱好
        # q7=models.Book.objects.filter(title='go法典').values_list("author__detail__hobby")
        # print(q7)
        #
    View Code

    增加

    models.UserInfo.objects.create(name="张三")

    修改

    删除

     del_obj = models.Publisher.objects.get(id=del_id)
            # 删除
            del_obj.delete()

     其他技巧

    自定义数据类型

    from django.db import models
    '''
    自定义char字段
    '''
    class FixedCharField(models.Field):
        """
        自定义的char类型的字段类
        """
        def __init__(self, max_length, *args, **kwargs):
            super().__init__(max_length=max_length, *args, **kwargs)
            self.length = max_length
    
        def db_type(self, connection):
            """
            限定生成数据库表的字段类型为char,长度为length指定的值
            """
            return 'char(%s)' % self.length
    View Code

    在python脚本中调用django环境

    import os
    
    if __name__ == '__main__':
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
        import django
        django.setup()
    
        from app01 import models
    
        books = models.Book.objects.all()
        print(books)

     在django终端打印sql语句

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }

     

  • 相关阅读:
    shell脚本while read line的使用
    shell 一次性赋值多个变量
    Docker Volume
    nginx反向代理与负载均衡
    lua中 table.getn(t) 、#t、 table.maxn(t) 这三个什么区别?
    pv绑定pvc
    使用brew services管理服务
    Kubernetes中强制删除Pod、namespace
    shell 中的${},##, %% , :- ,:+, ? 的使用
    petalinux中fsbl源码
  • 原文地址:https://www.cnblogs.com/huay/p/11306873.html
Copyright © 2011-2022 走看看