Django基础-2:Django常用配置及ORM-创新互联

小生博客:http://xsboke.blog.51cto.com

成都创新互联服务项目包括紫云网站建设、紫云网站制作、紫云网页制作以及紫云网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,紫云网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到紫云省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
-------谢谢您的参考,如有疑问,欢迎交流

本次主要收集了在django中经常使用到的配置.便于大家查询

目录:

  1. 汉化admin,时间格式化,指定statics.
  2. 注册models,自定义admin.
  3. 初始化models,创建超级用户.
  4. ORM.
  5. ORM的使用

一. 常用配置

  1. 汉化admin,时间格式化,指定statics.

    汉化admin,指定时区

    LANGUAGE_CODE = 'zh_Hans'
    TIME_ZONE = 'Asia/Bangkok'

    格式化时间显示

    USE_L10N = False
    DATETIME_FORMAT = 'Y-m-d H:i:s'
    DATE_FORMAT = 'Y-m-d'

    指定static

    STATIC_URL = '/static/'
    STATICFILES_DIRS = (
    os.path.join(BASE_DIR,"statics"),
    )

  2. 注册models,自定义admin

    from app.models import *
    admin.site.site_header = '服务器续费信息' # 此处设置页面显示标题
    admin.site.site_title = '服务器续费信息' # 此处设置页面头部标题

    @admin.register(TableName)
    class TNAdmin(admin.ModelAdmin):
    fields = ('issue','start_date','applicant','result','receiver','end_date','memo') # 设置编辑界面显示的字段
    list_display = ('number','issue','start_date','applicant','result','receiver','end_date') # 设置在列表中显示的字段
    search_fields = ('start_date',) #增加一个搜索栏
    empty_value_display = '未填写' # 覆盖空字段为短划线
    list_per_page = 50 # 每页显示的行数
    ordering = ('-number',) # 设置默认排序字段,-为降序
    list_editable = ['result',] # 设置可编辑字段
    list_display_links = ('id', 'caption') # 设置哪些字段可以点击进入编辑界面
    date_hierarchy = 'start_date' # 详细时间分层筛选 
    list_filter = ('start_date','end_date','receiver','result') # 过滤器

  3. 初始化models,创建超级用户.

    python manage.py makemigrations
    python manage.py migrate

    python manage.py createsuperuser

  4. 什么是ORM

    ORM,对象关系映射,是一个对应关系,用于实现面向对象编程语言里不同类型系统的数据之间的转换,换言之,就是用面向对象的方式去操作数据库的创建表以及增删改查等操作。

    优点:
    1.1 ORM使得我们的通用数据库交互变得简单易行,而且完全不用考虑该死的SQL语句,快速开发,由此而来
    1.2 可以避免一些新手程序要写sql语句带来的性能问题

    缺点:
    1.3 性能有所牺牲,不过现在的各种ORM框架都在尝试各种方法,比如缓存,延迟加载等来减轻这个问题
    1.4 对于个别复杂查询,ORM仍力不从心,为了解决这个问题,ORM一般也支持写raw sql。

二. ORM的使用

2.1 创建表
    创建单表
    创建关联表:foreignkey(通过外键关联)
                表之间的关系:
                    一对一
                    一对多
                    多对多

2.2 创建单表
    # 表创建完之后需要生成,执行两条命令
    # python manage.py makemigrations
    # python manage.py migrate
    from django.db import models

    class 表名(models.Model):
        字段名 = models.字段属性(属性值)

        def __str__(self):      # 防止打印对象时,输出内存地址
            return self.<要打印的变量>

            字段属性:
                字段名 = models.CharField(max_length=64)
                        CharField           :较短的字符串
                        IntegerField        :数字
                        ForeignKey          :
                        ManyToManyField     :

    2.2.1 单表的增,建议使用create第二种
            create方式一:
                表名.object.create(
                    字段1=要插入的数据1,
                    字段2=要插入的数据2,
                    字段3=要插入的数据3,
                )

            create方法二:以字典的方式插入
                表名.object.create(**{"字段1":"数据1"})

            save方法一:
                变量=表名(字段1="数据1")
                变量.save()

            save方法二:
                变量=表名()
                变量.字段="数据1"
                变量.save()

    2.2.3 单表的删除         
            表名.objects.filter(条件).deleter()

    2.2.3 单表的修改
            update方法:filter调用的是一个集合,效率比save高
                表名.objects.filter(条件1,条件2).update(字段=数据)

            save方法(相当于重新赋值):get调用的是一个对象
                变量 = 表名.objects.get(条件)
                变量.字段=数据
                变量.save()

    2.2.4 单表的查询

        <1>查数据
            变量 = models.表名.objects.filter(id=2)[0]  # 取出过滤出id=2的,第一行

            filter(**kwargs)            :包含与所给筛选条件相匹配的对象

            all()                       :查询所有结果

            变量 = models.表名.objects.filter(id=2).values("字段")
            # 返回一个列表,列表中包含字典,字典里面存放的是"字段:数据"
            # [{"字段1":"数据1"},{"字段2":"数据2"}]

        <2>查到数据后的操作,在.filter和.all的后面
            exclude(**kwargs)           :包含与所给筛选条件不匹配的对象

            order_by(*field)            :对查询结果排序
            # 正序:   变量 = models.表名.objects.order_by("id")
            # 倒序:   变量 = models.表名.objects.order_by("-id")

            reverse()                   :对查询结果反向排序

            distinct()                  :从返回结果中剔除重复记录

            values_list(*field)         :与values()相似,返回一个元组序列

            count()                     :返回数据库中匹配查询的对象数量

            first()                     :返回第一条记录

            last()                      :返回最后一条记录

            exists()                    :如果QuerySet包含数据,就返回True,否则返回False

            惰性机制:
                表名.objects.all()或者.filter()等都只是返回一个QuerySet(查询结果集对象),
                它并不会马上执行sql,而是当调用QuerySet的时候才执行。

            QuerySet特点:
                1. 可迭代
                2. 可切片
                    objs = models.表名.objects.all()

                    #迭代
                        for obj in objs:
                            print("obj:",obj)

                    #切片
                        print(objs[1])
                        print(objs[1:4])
                        print(objs[::-1])

3. 多表

    3.1 一对多(ForeignKey),比如 表1:"出版社" 和 表2:"书",一个出版社可以出多本书,外键要放在多里面
            class 出版社表(models.Model):
                出版社名 = models.CharField(max_length=30)
                出版社地址 = models.CharField(max_length=30)

            class 书表(models.Model):
                书名 = models.CharField(max_length=30)
                出版社 = models.ForeignKey("出版社表")
                # 对于外键,ForeignKey,在数据库中,Django会自动将字段存为"出版社_id"

            # 当有外键时需要插入数据,写为

                # 第一种插入方式

                    书表.objects.create (
                        书名 = "鲁滨逊流浪记"
                        出版社_id = "1"  // 直接插入
                    )

                # 第二种插入方式       

                    pub = models.出版社表.objects.filter(id=1)  # 首先实例化一个对象
                        书表.objects.create (
                            书名 = "鲁滨逊流浪记"
                            出版社 = pub[0]  # 然后插入
                        )

    3.2 多对多(ManyToManyField)
        比如作者和书,一个作者可以写作本书,一本书可以由多个作者完成,这时候外键放哪都行

            class 书表(models.Model):
                书名 = models.CharField(max_length=30)
                作者 = models.ManyToManyField("作者表")  # 自动创建第三张表

            class 作者表(models.Model):
                作者名 = models.CharField(max_length=64)

        这时候会产生一个表,结构为:
            id      书表_id       作者表_id
             1         5           4
             2         5           1
             3         5           2
             4         6           1
             5         6           1

        插入数据的方法:
            # 给一本书添加两个作者

            作者1 = models.作者表.objects.get(id=3)
            作者1 = models.作者表.objects.get(id=4)

            书表 = models.书表.objects.filter(id=3)[0]

            # 一下三种方式都可
                书表.作者.add(作者1,作者2)

                书表.作者.add(作者1)
                书表.作者.add(作者2)

                书表.作者.add(*[作者1,作者2])

                执行完之后。映射表的内容为:
                    id      书表_id       作者表_id
                    1           3           3
                    2           3           4

        第三张表可以自己创建:
            class 书表(models.Model):
                书名 = models.CharField(max_length=30)
                作者 = models.ManyToManyField("作者表")  # 自动创建第三张表

            class 作者表(models.Model):
                作者名 = models.CharField(max_length=64)

            class 第三张表(models.Model):
                书 = models.ForeignKey(书表)
                作者 = models.ForeignKey(作者表)

                class Meta:                        # 定义表的相关属性
                    unique_together=["书","作者"]  # 联合唯一,根据需求定义

                   id         书_id       作者_id
                    1           3           3    # 为了避免这种情况出现,表在创建的时候要做一个联合唯一的属性
                    2           3           3    # 为了避免这种情况出现,表在创建的时候要做一个联合唯一的属性
                    3           3           4               

    3.3 一对一
        OneToOne:一个通过两个Foreignkey,unqiue=True

4. 查询
    4.1 对象查询
        通过将查询到的数据赋予给一个变量,这就叫对象查询

        4.1.1 正向查找
            # 需求:找到书所在出版社的城市,其中书是一个表,出版社是一个表,出版社里面包括城市
            # 其中,书表外键到了出版社表
            obj = models.书表.objects.filter(书名="鲁滨逊流浪记")[0]
            obj.外键.城市       # 可以通过外键,调用另一个表的字段

        4.1.2 反向查找
            # 现在有一个出版社表,一个书表,外键在书表
            # 现在需要将某个出版社出版的所有的书输出
            obj = models.出版社表.objects.filter(name="人民出版社")
            obj.书表_set.all().values("书名")       # 通过 "表名_set" 这种格式反向查找

    4.2 双下划线之单表条件查询

        models.表1.objects.filter(id__lt=10,id__gt=1)  # 获取id大于1且小于10的值
        models.表1.objects.filter(id__in=[11,22,33])   # 获取id等于11/22/33的数据
        models.表1.objects.exclude(id_in=[11,22,33])   # 不等于

        models.表1.objects.filter(name__contains="ven")   # 与sql的模糊查询类似
        models.表1.objects.filter(name__icontains="ven")  # icontains大小写不敏感

        models.表1.objects.filter(id__range=[1,2])        # 范围,bettwen and

        startswith(以什么开头)、istartwith、endswith(以什么结尾)、iendwith

    4.3 双下划线之关联表查询
        # 把所有书名叫鲁滨逊流浪记的出版社打印
        models.出版社表.objects.filter(书表__书名="鲁滨逊流浪记").vaules("出版社名").distinct()

        # 打印人民出版社出版的书
        models.书表.objects.filter(出版社表__出版社名="人民出版社").values("书名")

        # 打印出,出版鲁滨逊流浪记的出版社
        models.书表.objects.filter(书表__书名="鲁滨逊流浪记").values("外键__出版社名")

    4.4 聚合查询和分组查询,是一种聚合函数

        from django.db.models import Avg,Min,Sum,Max

        Avg,Min,Sum,Max 是聚合方法

        <1> 聚合查询
            在最后查询的结果集上进行操作,只有一个结果
            aggregate(*args,**kwargs)

            # 作者wangyi发表的书价格的一个平均值
                书表.objects.all().aggregate(Avg('价格'))

        <2> 分组查询
            先根据条件把所有的结果进行一个分组,然后对每一个结果进行操作
            annotate(*args,**kwargs) 

            # 查询每一个作者出的书价格的总价格
                书表.objects.values("作者表__作者名").annotate(Sum("price"))

    4.5 F查询和Q查询

        4.5.1 F 查询,使用查询条件的值,专门取对象中某列值的操作
            from django.db.models import F,Q
            # 给每本书增加20块钱

                models.书表.objects.all().update(价格=F('价格')+20)  # 只支持数字

        4.5.2 Q 查询,用于封装关键字查询
            之前的查询都是单关键字查询,也有用过双关键字,但是是用逗号分隔,代表and;
            可是如果我想用或呢,或者我想用or里面包括and,例如:  a and (b or (d and e))

            from django.db.models import F,Q

            如果这样写,这两个语句的结果都是一样的:
                        obj = models.书表.objects.filter(id=3)[0]     
                        obj = models.书表.objects.filter(Q(id=3))[0]

            示例Q查询的多关键字查询

                obj = models.书表.objects.filter( Q(id=3) | Q(书名="鲁滨逊流浪记") )  #  使用管道符"|"实现or方法

                obj = models.书表.objects.filter( Q(价格__gt=50)  & (Q(id=3) | Q(书名="鲁滨逊流浪记")) )    # 价格大于50并且(id=3或者书名=鲁滨逊流浪记的书)

                obj = models.书表.objects.filter( Q(价格__gt=50)  & (Q(id=3) | Q(书名="鲁滨逊流浪记")) , 颜色="红色" )    # 用普通查询加Q查询,普通查询必须放在Q查询后面(查询(价格大于50并且(id=3或者书名=鲁滨逊流浪记)并且颜色为红色的书)

5. 注意,创建表的时候,为了防止返回内存参数,建议写为如下样式
    class 书表(models.Model):
                书名 = models.CharField(max_length=30)
                作者 = models.ManyToManyField("作者表") 

                def __str__(self)
                    return self.书名          # 将需要返回的数据使用str方法返回

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


文章题目:Django基础-2:Django常用配置及ORM-创新互联
URL标题:http://pwwzsj.com/article/dcsico.html