Python全栈之路-Django(九)

1 ORM操作

1.常用ORM操作

models.UserInfo.objects.all()
models.UserInfo.objects.filter(id=1,name='wyz') # filter内的条件为and
models.UserInfo.objects.first()    # 不是一个QuerySet对象
models.UserInfo.objects.count()    # 计算行数
models.UserInfo.objects.create()
models.UserInfo.objects.update()
models.UserInfo.objects.delete()
models.UserInfo.objects.all()[start,end]  # limit 
models.UserInfo.objects.all().values(x,y,...)
models.UserInfo.objects.filter(id__gt=1).values_list(x,y,...)
# QuerySet可以调用.values、.values_list

2.其他

app01.models.py

from django.db import models

# Create your models here.


class UserType(models.Model):
    title = models.CharField(max_length=32)


class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    ut = models.ForeignKey('UserType')

    def __str__(self):
        return "%s-%s" % (self.id, self.name)

app01.views.py

# 数据库操作
from app01 import models
def test(request):
    # http://www.cnblogs.com/wupeiqi/articles/6216618.html
    # 排序
    user_list = models.UserInfo.objects.all().order_by('id') # 升序
    print(user_list)
    user_list = models.UserInfo.objects.all().order_by('-id') # 降序 '-' 代表降序
    print(user_list)
    user_list = models.UserInfo.objects.all().order_by('-id','name') # 按照id降序,按照name升序
    print(user_list)

    # 分组
    # 1. 不带where和having条件的分组
    from django.db.models import Count, Sum, Max, Min
    # v = models.UserInfo.objects.values('ut_id').annotate(xxx=Count('id'))
    # print(v.query)
    # # SELECT "app01_userinfo"."ut_id", COUNT("app01_userinfo"."id") AS "xxx" FROM "app01_userinfo" GROUP BY "app01_userinfo"."ut_id"

    # 2. 带having条件的分组
    # v = models.UserInfo.objects.values('ut_id').annotate(xxx=Count('id')).filter(xxx__gt=2)
    # print(v.query)
    # # SELECT "app01_userinfo"."ut_id", COUNT("app01_userinfo"."id") AS "xxx" FROM "app01_userinfo" GROUP BY "app01_userinfo"."ut_id" HAVING COUNT("app01_userinfo"."id") > 2

    # 3. 带where和having条件的分组
    v = models.UserInfo.objects.values('ut_id').filter(id__gt=2).annotate(xxx=Count('id')).filter(xxx__gt=2)
    print(v.query)
    # SELECT "app01_userinfo"."ut_id", COUNT("app01_userinfo"."id") AS "xxx" FROM "app01_userinfo" WHERE "app01_userinfo"."id" > 2 GROUP BY "app01_userinfo"."ut_id" HAVING COUNT("app01_userinfo"."id") > 2

    # in range startswith endswith contains
    models.UserInfo.objects.filter(id__in=[1,2,3])
    models.UserInfo.objects.filter(id__range=[1,3])
    models.UserInfo.objects.filter(name__startswith="xxx")
    models.UserInfo.objects.filter(name__endswith="xxx")
    models.UserInfo.objects.filter(name__contains="xxx")
    # 不等于 id != 1
    models.UserInfo.objects.exclude(id=1)

    # F
    from django.db.models import F
    # 所有人的年龄加一
    # F是用来做更新时获取该字段原始的值
    # models.UserInfo.objects.all().update(age=F("age")+1)

    # Q
    # Q是用来解决一些查询问题 用于构造复杂的查询条件
    models.UserInfo.objects.filter(id=1, name='root')
    # 上面的写法可以用以下代码代替,即把条件写到一个字典中,但是默认还是用and
    condition = {
        'id': 1,
        'name': 'root'
    }
    models.UserInfo.objects.filter(**condition)

    from django.db.models import Q
    # 第一种写法 对象方式
    # | 表示or & 表示and
    models.UserInfo.objects.filter(Q(id=1))
    models.UserInfo.objects.filter(Q(Q(id=1) | Q(name='root')))
    models.UserInfo.objects.filter(Q(Q(id=1) & Q(name='root')))

    # 第二种写法 方法方式 推荐使用



    con = Q()

    q1 = Q()
    q1.connector = 'OR'
    q1.children.append(('id', 1))
    q1.children.append(('id', 10))
    q1.children.append(('id', 9))

    q2 = Q()
    q2.connector = 'OR'
    q2.children.append(('name', 'root'))
    q2.children.append(('name', 'wyz'))
    q2.children.append(('name', 'shz'))

    con.add(q1, 'AND')
    con.add(q2, 'AND')
    # (id=1 or id=10 or id=9) and (c1=1 or c1=10 or c1=9)
    models.UserInfo.objects.filter(con)

    # 通过字典动态添加
    condition_dict = {
        'k1': [1, 2, 3, 4],
        'k2': [12],
        'k3': [13, 14],

    }
    con = Q()
    for k, v in condition_dict:
        q = Q()
        q.connector = 'OR'
        for i in v:

            q.children.append(('id', i))
        con.add(q, 'AND')
    models.UserInfo.objects.filter(con)

    # extra 额外的查询条件以及相关表和排序操作
    """
    select id,name,(select count(1) from tb) as n from tb;
    """
    # select自定义列 & select_params & order_by
    v = models.UserInfo.objects.all().extra(
        select={
            'n': "select count(1) from app01_userinfo where id>%s and id < %s",
            'm': "select count(1) from app01_userinfo where id>%s and id < %s"
        },
        select_params=[1, 5, 2, 4], order_by=['-id']
    )
    for obj in v:
        print(obj.name, obj.id, obj.n, obj.m)
    # where条件 & select_params
    models.UserInfo.objects.extra(
        where=['id=%s or id=%s', 'name="%s"'],
        select_params=[1, 2, 'root']
    )

    # 笛卡尔积
    models.UserInfo.objects.extra(
        tables=['app01_usertype'],
        where=['app01_usertype.id = app01_userinfo.ut_id']
    )

    # extra 应用及SQL语句转换
    """
    models.UserInfo.objects.extra(
        select={'newid':'select count(1) from app01_usertype where id>%s'},
        select_params=[1,],
        where = ['age>%s'],
        params=[18,],
        order_by=['-age'],
        tables=['app01_usertype']
    )

    select 
        app01_userinfo.id,
        (select count(1) from app01_usertype where id>1) as newid
    from app01_userinfo,app01_usertype
    where 
        app01_userinfo.age > 18
    order by 
        app01_userinfo.age desc
    """
    # 原生SQL语句
    from django.db import connection, connections
    # settings.py
    # DATABASES = {
    #     'default': {
    #         'ENGINE': 'django.db.backends.sqlite3',
    #         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    #     },
    #     'db2': {
    #         'ENGINE': 'django.db.backends.sqlite3',
    #         'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),
    #     }
    # }

    # cursor = connection.cursor()  # connection=default数据
    cursor = connections['db2'].cursor() # 自定义连接数据库

    cursor.execute("""SELECT * from auth_user where id = %s""", [1])

    row = cursor.fetchone()
    row = cursor.fetchall()

    # ORM补充
    # distinct去重
    models.UserInfo.objects.values('id').distinct()
    # select distinct id from userinfo
    # 连接PostgreSQL写法:
    # models.UserInfo.objects.distinct('id')

    # 倒序
    # 如果没有order_by,则reverse没有任何作用
    models.UserInfo.objects.all().order_by('-id').reverse()
    # 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序
    # 仅取某个表中的数据
    # only
    models.UserInfo.objects.only('name', 'id')
    # 或
    models.UserInfo.objects.filter(...).only('name', 'id')
    # defer
    models.UserInfo.objects.defer('name', 'id')
    # 或
    models.UserInfo.objects.filter(...).defer('name', 'id')
    # 映射中排除某列数据
    # using
    # 指定使用的数据库,参数为别名(setting中的设置)
    models.UserInfo.objects.all().using('db2')

    # QuerySet类型可以无限往下.  values values_list后面就不能.了

    # date
    # 根据时间进行某一部分进行去重查找并截取指定内容
    # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
    # order只能是:"ASC"  "DESC"
    # 并获取转换后的时间
    # - year: 年 - 01 - 01
    # - month: 年 - 月 - 01
    # - day: 年 - 月 - 日
    # models.DatePlus.objects.dates('ctime', 'day', 'DESC')
    # datetimes
    # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
    # kind只能是 "year", "month", "day", "hour", "minute", "second"
    # order只能是:"ASC"  "DESC"
    # tzinfo时区对象
    # models.DDD.objects.datetimes('ctime', 'hour', tzinfo=pytz.UTC)
    # models.DDD.objects.datetimes('ctime', 'hour', tzinfo=pytz.timezone('Asia/Shanghai'))
    #
    # """
    # pip3 install pytz
    # import pytz
    # pytz.all_timezones
    # pytz.timezone(‘Asia/Shanghai’)
    # """

    # none
    # 空QuerySet对象
    models.UserInfo.objects.none()

    # aggregate
    # 聚合函数,获取字典类型聚合结果
    from django.db.models import Count, Avg, Max, Min, Sum
    result = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))
    # === > {'k': 3, 'n': 4}

    # get
    models.UserInfo.objects.get(id=1)
    # get的缺点,获取不到值会抛异常,获取到多个值也会抛异常 所以建议用first

    # create 接字典格式参数
    obj = models.UserInfo.objects.create(**{'title': 'xxx'})
    # 对比 obj = models.UserInfo.objects.create(title='xxx')
    # obj为创建的最后一条数据
    # obj.id 为自增id列
    # 其他创建方式
    # obj = models.UserInfo(title='xxx')
    # obj.save()

    # bulk_create
    # 批量插入
    # batch_size表示一次插入的个数 建议不超过999
    # objs = [
    #     models.DDD(name='r11'),
    #     models.DDD(name='r22')
    # ]
    # models.DDD.objects.bulk_create(objs, 10)

    # update_or_create
    # 如果存在,则更新,否则,创建
    # defaults 指定创建时或更新时的其他字段
    # obj, created = models.UserInfo.objects.update_or_create(
    #     username='root1',
    #     defaults={'email': '1111111', 'u_id': 2, 't_id': 1}
    # )
    # obj创建成功的对象
    # get_or_create
    # 如果存在,则获取,否则,创建
    # defaults 指定创建时,其他字段的值
    obj, created = models.UserInfo.objects.get_or_create(
        username='root1',
        defaults={'email': '1111111', 'u_id': 2, 't_id': 2}
    )
    # update_or_create  get_or_create 除了default指定的参数其他都是查询条件,并且为and

    # in_bulk
    # 根据主键ID进行查找
    # id_list = [11, 21, 31]
    # models.DDD.objects.in_bulk(id_list)

    # raw
    # 执行原生SQL
    # models.UserInfo.objects.raw('select * from userinfo')
    #
    # # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名
    # models.UserInfo.objects.raw('select id as nid from 其他表')
    #
    # # 为原生SQL设置参数
    # models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12, ])
    #
    # # 将获取的到列名转换为指定列名
    # name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
    # Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
    #
    # # 指定数据库
    # models.UserInfo.objects.raw('select * from userinfo', using="default")

    #exists
    # 是否有结果 返回bool值

    return HttpResponse('...')

3 XSS攻击

1.html模板中慎用safe 和 mark_safe
2.一定要用,一定要过滤关键字

原文地址:https://www.cnblogs.com/wanyuetian/p/7118783.html