• Django(6)-orm


    Django ORM 常用字段和参数

    常用字段

    AutoField

    int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。

    IntegerField

    一个整数类型,范围在 -2147483648 to 2147483647。

    CharField

    字符类型,必须提供max_length参数, max_length表示字符长度。

    DateField

    日期字段,日期格式  YYYY-MM-DD,相当于Python中的datetime.date()实例。

    DateTimeField

     日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。

     

       AutoField(Field)
            - int自增列,必须填入参数 primary_key=True
    
        BigAutoField(AutoField)
            - bigint自增列,必须填入参数 primary_key=True
    
            注:当model中如果没有自增列,则自动会创建一个列名为id的列
            from django.db import models
    
            class UserInfo(models.Model):
                # 自动创建一个列名为id的且为自增的整数列
                username = models.CharField(max_length=32)
    
            class Group(models.Model):
                # 自定义自增列
                nid = models.AutoField(primary_key=True)
                name = models.CharField(max_length=32)
    
        SmallIntegerField(IntegerField):
            - 小整数 -3276832767
    
        PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
            - 正小整数 032767
        IntegerField(Field)
            - 整数列(有符号的) -21474836482147483647
    
        PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
            - 正整数 02147483647
    
        BigIntegerField(IntegerField):
            - 长整型(有符号的) -92233720368547758089223372036854775807
    
        BooleanField(Field)
            - 布尔值类型
    
        NullBooleanField(Field):
            - 可以为空的布尔值
    
        CharField(Field)
            - 字符类型
            - 必须提供max_length参数, max_length表示字符长度
    
        TextField(Field)
            - 文本类型
    
        EmailField(CharField):
            - 字符串类型,Django Admin以及ModelForm中提供验证机制
    
        IPAddressField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
    
        GenericIPAddressField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
            - 参数:
                protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
                unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"
    
        URLField(CharField)
            - 字符串类型,Django Admin以及ModelForm中提供验证 URL
    
        SlugField(CharField)
            - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
    
        CommaSeparatedIntegerField(CharField)
            - 字符串类型,格式必须为逗号分割的数字
    
        UUIDField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
    
        FilePathField(Field)
            - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
            - 参数:
                    path,                      文件夹路径
                    match=None,                正则匹配
                    recursive=False,           递归下面的文件夹
                    allow_files=True,          允许文件
                    allow_folders=False,       允许文件夹
    
        FileField(Field)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
    
        ImageField(FileField)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
                width_field=None,   上传图片的高度保存的数据库字段名(字符串)
                height_field=None   上传图片的宽度保存的数据库字段名(字符串)
    
        DateTimeField(DateField)
            - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
    
        DateField(DateTimeCheckMixin, Field)
            - 日期格式      YYYY-MM-DD
    
        TimeField(DateTimeCheckMixin, Field)
            - 时间格式      HH:MM[:ss[.uuuuuu]]
    
        DurationField(Field)
            - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
    
        FloatField(Field)
            - 浮点型
    
        DecimalField(Field)
            - 10进制小数
            - 参数:
                max_digits,小数总长度
                decimal_places,小数位长度
    
        BinaryField(Field)
            - 二进制类型
    字段合集

    自定义字段(了解为主)

    class UnsignedIntegerField(models.IntegerField):
        def db_type(self, connection):
            return 'integer UNSIGNED'
    ================================
    
    class FixedCharField(models.Field):
        """
        自定义的char类型的字段类
        """
        def __init__(self, max_length, *args, **kwargs):
            self.max_length = max_length
            super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs)
    
        def db_type(self, connection):
            """
            限定生成数据库表的字段类型为char,长度为max_length指定的值
            """
            return 'char(%s)' % self.max_length
    
    
    class Class(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=25)
        # 使用自定义的char类型的字段
        cname = FixedCharField(max_length=25)
    自定义字段

    ORM字段与数据库实际字段的对应关系

        'AutoField': 'integer AUTO_INCREMENT',
        'BigAutoField': 'bigint AUTO_INCREMENT',
        'BinaryField': 'longblob',
        'BooleanField': 'bool',
        'CharField': 'varchar(%(max_length)s)',
        'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
        'DateField': 'date',
        'DateTimeField': 'datetime',
        'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
        'DurationField': 'bigint',
        'FileField': 'varchar(%(max_length)s)',
        'FilePathField': 'varchar(%(max_length)s)',
        'FloatField': 'double precision',
        'IntegerField': 'integer',
        'BigIntegerField': 'bigint',
        'IPAddressField': 'char(15)',
        'GenericIPAddressField': 'char(39)',
        'NullBooleanField': 'bool',
        'OneToOneField': 'integer',
        'PositiveIntegerField': 'integer UNSIGNED',
        'PositiveSmallIntegerField': 'smallint UNSIGNED',
        'SlugField': 'varchar(%(max_length)s)',
        'SmallIntegerField': 'smallint',
        'TextField': 'longtext',
        'TimeField': 'time',
        'UUIDField': 'char(32)',
    ORM字段与数据库实际字段的对应关系

    字段参数

    null

    用于表示某个字段可以为空。

    unique

    如果设置为unique=True 则该字段在此表中必须是唯一的 。

    db_index

    如果db_index=True 则代表着为此字段设置索引。

    default

    为该字段设置默认值。

    DateField和DateTimeField

    auto_now_add
    配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
    auto_now
    配置上auto_now=True,每次更新数据记录的时候会更新该字段。

    关系字段

    ForeignKey

    字段参数

    OneToOneField

    字段参数

    to

    设置要关联的表。

    to_field

    设置要关联的字段。

    on_delete

    同ForeignKey字段。

    ManyToManyField

    字段参数

    元信息

    db_table

    ORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名。

    index_together

    联合索引。

    unique_together

    联合唯一索引。

    ordering

    指定默认按什么字段排序。

    只有设置了该属性,我们查询到的结果才可以被reverse()。

    __exact 精确等于 like ‘aaa’
    __iexact 精确等于 忽略大小写 ilike ‘aaa’
    __contains 包含 like ‘%aaa%’
    __icontains 包含 忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。
    __gt 大于
    __gte 大于等于
    __lt 小于
    __lte 小于等于
    __in 存在于一个list范围内
    __startswith 以…开头
    __istartswith 以…开头 忽略大小写
    __endswith 以…结尾
    __iendswith 以…结尾,忽略大小写
    __range 在…范围内
    __year 日期字段的年份
    __month 日期字段的月份
    __day 日期字段的日
    __isnull=True/False
    __isnull=True 与 __exact=None的区别
    
    class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()
    
    def __unicode__(self):
    return self.name
    
    class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()
    
    def __unicode__(self):
    return self.name
    
    class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateTimeField()
    authors = models.ManyToManyField(Author)
    
    def __unicode__(self):
    return self.headline
    
    这是model,有blog,author,以及entry;其中entry分别与blog与author表关 联,entry与blog表是通过 外键(models.ForeignKey())相连,属于一对多的关系,即一个entry对应多个blog,entry与author是多对多的关系, 通过modles.ManyToManyField()实现。
    一、插入数据库,用save()方法实现,如下:
    >>> from mysite.blog.models import Blog
    >>> b = Blog(name=’Beatles Blog’, tagline=’All the latest Beatles news.’)
    >>> b.save()
    
    二、更新数据库,也用save()方法实现,如下:
    >> b5.name = ‘New name’
    >> b5.save()
    
    保存外键和多对多关系的字段,如下例子:
    更新外键字段和普通的字段一样,只要指定一个对象的正确类型。
    >>> cheese_blog = Blog.objects.get(name=”Cheddar Talk”)
    >>> entry.blog = cheese_blog
    >>> entry.save()
    
    更新多对多字段时又一点不太一样,使用add()方法添加相关联的字段的值。
    >> joe = Author.objects.create(name=”Joe”)
    >> entry.authors.add(joe)
    
    三、检索对象
    
    >>> Blog.objects
    
    >>> b = Blog(name=’Foo’, tagline=’Bar’)
    >>> b.objects
    Traceback:
    …
    AttributeError: “Manager isn’t accessible via Blog instances.”
    
    1、检索所有的对象
    
    >>> all_entries = Entry.objects.all()
    
    使用all()方法返回数据库中的所有对象。
    
    2、检索特定的对象
    使用以下两个方法:
    fileter(**kwargs)
    返回一个与参数匹配的QuerySet,相当于等于(=).
    exclude(**kwargs)
    返回一个与参数不匹配的QuerySet,相当于不等于(!=)。
    
    Entry.objects.filter(pub_date__year=2006)
    不使用Entry.objects.all().filter(pub_date__year=2006),虽然也能运行,all()最好再获取所有的对象时使用。
    上面的例子等同于的sql语句:
    slect * from entry where pub_date_year=’2006′
    
    链接过滤器:
    >>> Entry.objects.filter(
    … headline__startswith=’What’
    … ).exclude(
    … pub_date__gte=datetime.now()
    … ).filter(
    … pub_date__gte=datetime(2005, 1, 1)
    … )
    
    最后返回的QuerySet是headline like ‘What%’ and put_date2005-01-01
    
    另外一种方法:
    >> q1 = Entry.objects.filter(headline__startswith=”What”)
    >> q2 = q1.exclude(pub_date__gte=datetime.now())
    >> q3 = q1.filter(pub_date__gte=datetime.now())
    这种方法的好处是可以对q1进行重用。
    
    QuerySet是延迟加载
    只在使用的时候才会去访问数据库,如下:
    >>> q = Entry.objects.filter(headline__startswith=”What”)
    >>> q = q.filter(pub_date__lte=datetime.now())
    >>> q = q.exclude(body_text__icontains=”food”)
    >>> print q
    在print q时才会访问数据库。
    
    其他的QuerySet方法
    >>> Entry.objects.all()[:5]
    这是查找前5个entry表里的数据
    
    >>> Entry.objects.all()[5:10]
    这是查找从第5个到第10个之间的数据。
    
    >>> Entry.objects.all()[:10:2]
    这是查询从第0个开始到第10个,步长为2的数据。
    
    >>> Entry.objects.order_by(‘headline’)[0]
    这是取按headline字段排序后的第一个对象。
    
    >>> Entry.objects.order_by(‘headline’)[0:1].get()
    这和上面的等同的。
    
    >>> Entry.objects.filter(pub_date__lte=’2006-01-01′)
    等同于SELECT * FROM blog_entry WHERE pub_date <= ’2006-01-01′; >>> Entry.objects.get(headline__exact=”Man bites dog”)
    等同于SELECT … WHERE headline = ‘Man bites dog’;
    
    >>> Blog.objects.get(id__exact=14) # Explicit form
    >>> Blog.objects.get(id=14) # __exact is implied
    这两种方式是等同的,都是查找id=14的对象。
    
    >>> Blog.objects.get(name__iexact=”beatles blog”)
    查找name=”beatles blog”的对象,不去饭大小写。
    
    Entry.objects.get(headline__contains=’Lennon’)
    等同于SELECT … WHERE headline LIKE ‘%Lennon%’;
    
    startswith 等同于sql语句中的 name like ‘Lennon%’,
    endswith等同于sql语句中的 name like ‘%Lennon’.
    
    >>> Entry.objects.filter(blog__name__exact=’Beatles Blog’)
    查找entry表中外键关系blog_name=’Beatles Blog’的Entry对象。
    
    >>> Blog.objects.filter(entry__headline__contains=’Lennon’)
    查找blog表中外键关系entry表中的headline字段中包含Lennon的blog数据。
    
    Blog.objects.filter(entry__author__name=’Lennon’)
    查找blog表中外键关系entry表中的author字段中包含Lennon的blog数据。
    
    Blog.objects.filter(entry__author__name__isnull=True)
    Blog.objects.filter(entry__author__isnull=False,entry__author__name__isnull=True)
    查询的是author_name为null的值
    
    Blog.objects.filter(entry__headline__contains=’Lennon’,entry__pub_date__year=2008)
    Blog.objects.filter(entry__headline__contains=’Lennon’).filter( entry__pub_date__year=2008)
    这两种查询在某些情况下是相同的,某些情况下是不同的。第一种是限制所有的blog数据的,而第二种情况则是第一个filter是
    限制blog的,而第二个filter则是限制entry的
    
    >>> Blog.objects.get(id__exact=14) # Explicit form
    >>> Blog.objects.get(id=14) # __exact is implied
    >>> Blog.objects.get(pk=14) # pk implies id__exact
    等同于select * from where id=14
    
    # Get blogs entries with id 1, 4 and 7
    >>> Blog.objects.filter(pk__in=[1,4,7])
    等同于select * from where id in{1,4,7}
    # Get all blog entries with id > 14
    >>> Blog.objects.filter(pk__gt=14)
    等同于select * from id>14
    
    >>> Entry.objects.filter(blog__id__exact=3) # Explicit form
    >>> Entry.objects.filter(blog__id=3) # __exact is implied
    >>> Entry.objects.filter(blog__pk=3) # __pk implies __id__exact
    这三种情况是相同的
    
    >>> Entry.objects.filter(headline__contains=’%')
    等同于SELECT … WHERE headline LIKE ‘%\%%’;
    
    Caching and QuerySets
    
    >>> print [e.headline for e in Entry.objects.all()]
    >>> print [e.pub_date for e in Entry.objects.all()]
    应改写为:
    >> queryset = Poll.objects.all()
    >>> print [p.headline for p in queryset] # Evaluate the query set.
    >>> print [p.pub_date for p in queryset] # Re-use the cache from the evaluation.、
    这样利用缓存,减少访问数据库的次数。
    
    四、用Q对象实现复杂的查询
    
    Q(question__startswith=’Who’) | Q(question__startswith=’What’)
    等同于WHERE question LIKE ‘Who%’ OR question LIKE ‘What%’
    
    Poll.objects.get(
    Q(question__startswith=’Who’),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
    )
    等同于SELECT * from polls WHERE question LIKE ‘Who%’ AND (pub_date = ’2005-05-02′ OR pub_date = ’2005-05-06′)
    
    Poll.objects.get(
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    question__startswith=’Who’)
    等同于Poll.objects.get(question__startswith=’Who’, Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))
    
    五、比较对象
    
    >>> some_entry == other_entry
    >>> some_entry.id == other_entry.id
    
    六、删除
    
    Entry.objects.filter(pub_date__year=2005).delete()
    
    b = Blog.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()
    
    Entry.objects.all().delete()
    删除所有
    
    七、一次更新多个值
    
    # Update all the headlines with pub_date in 2007.
    Entry.objects.filter(pub_date__year=2007).update(headline=’Everything is the same’)
    
    >>> b = Blog.objects.get(pk=1)
    # Change every Entry so that it belongs to this Blog.
    >>> Entry.objects.all().update(blog=b)
    
    如果用save()方法,必须一个一个进行保存,需要对其就行遍历,如下:
    for item in my_queryset:
    item.save()
    
    关联对象
    
    one-to-many
    >>> e = Entry.objects.get(id=2)
    >>> e.blog # Returns the related Blog object.
    
    >>> e = Entry.objects.get(id=2)
    >>> e.blog = some_blog
    >>> e.save()
    
    >>> e = Entry.objects.get(id=2)
    >>> e.blog = None
    >>> e.save() # “UPDATE blog_entry SET blog_id = NULL …;”
    
    >>> e = Entry.objects.get(id=2)
    >>> print e.blog # Hits the database to retrieve the associated Blog.
    >>> print e.blog # Doesn’t hit the database; uses cached version.
    
    >>> e = Entry.objects.select_related().get(id=2)
    >>> print e.blog # Doesn’t hit the database; uses cached version.
    >>> print e.blog # Doesn’t hit the database; uses cached version
    
    >>> b = Blog.objects.get(id=1)
    >>> b.entry_set.all() # Returns all Entry objects related to Blog.
    
    # b.entry_set is a Manager that returns QuerySets.
    >>> b.entry_set.filter(headline__contains=’Lennon’)
    >>> b.entry_set.count()
    
    >>> b = Blog.objects.get(id=1)
    >>> b.entries.all() # Returns all Entry objects related to Blog.
    # b.entries is a Manager that returns QuerySets.
    >>> b.entries.filter(headline__contains=’Lennon’)
    >>> b.entries.count()
    
    You cannot access a reverse ForeignKey Manager from the class; it must be accessed from an instance:
    >>> Blog.entry_set
    
    add(obj1, obj2, …)
    Adds the specified model objects to the related object set.
    create(**kwargs)
    Creates a new object, saves it and puts it in the related object set. Returns the newly created object.
    remove(obj1, obj2, …)
    Removes the specified model objects from the related object set.
    clear()
    Removes all objects from the related object set.
    
    many-to-many类型:
    e = Entry.objects.get(id=3)
    e.authors.all() # Returns all Author objects for this Entry.
    e.authors.count()
    e.authors.filter(name__contains=’John’)
    a = Author.objects.get(id=5)
    a.entry_set.all() # Returns all Entry objects for this Author.
    
    one-to-one 类型:
    class EntryDetail(models.Model):
    entry = models.OneToOneField(Entry)
    details = models.TextField()
    
    ed = EntryDetail.objects.get(id=2)
    ed.entry # Returns the related Entry object
    
    使用sql语句进行查询:
    
    def my_custom_sql(self):
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute(“SELECT foo FROM bar WHERE baz = %s”, [self.baz])
    row = cursor.fetchone()
    return row
    python django 数据库查询方法总结

    这里必须添加,models才能被记录

    课后习题

    表示7天的时间间隔,用于表示优惠券的过期时间
    为什么要定义一个char字段,char字段的作用是什么
    查book的所有对象
    title是围城
    id=1
    id大于2
    id小于2
    id大于等于2
    出版日期是2017年的书
    出版日期大于2017年的书
    书名包含围字的
    包含围字且出版年份是2018年的
    get方法与filter方法的区别
    取2018年出版的书的书名和出版日期
    取2018年出版的书的书名和出版日期,且返回列表形式
    
    
    CBV 中的META的table_name怎么取出来
    <9> distinct():            
    从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
      - models.CASCADE,删除关联数据,与之关联也删除
       DecimalField(Field)
            - 10进制小数
            - 参数:
                max_digits,小数总长度
                decimal_places,小数位长度

    DateField和DateTimeField

    auto_now_add

    配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

    db_constraint

    是否在数据库中创建外键约束,默认为True。

    db_index

    如果db_index=True 则代表着为此字段设置索引。

    #一对多或称为多对一
    三张表:出版社,作者信息,书
    
    一对多(或多对一):一个出版社可以出版多本书
    
    关联方式:foreign key
    #多对多
    三张表:出版社,作者信息,书
    
    多对多:一个作者可以写多本书,一本书也可以有多个作者,双向的一对多,即多对多
      
    关联方式:foreign key+一张新的表
  • 相关阅读:
    Httpclient请求数据(post)
    实现定位(无基本地图)
    Httpclient请求数据
    带参数路径的刷新和加载
    AsyncTask异步交互和httpurlconnection结合使用
    判断网络状态
    Android数字签名
    app加固
    定位和xml解析和gson解析加上拉加载,下拉刷新
    下载app后自动安装程序
  • 原文地址:https://www.cnblogs.com/shanjinghao/p/9203807.html
Copyright © 2020-2023  润新知