Python全棧之路-Django(十)

1 ORM補充

from app01 import models


def test(request):
    # select_related 自動關聯UserType表(inner join),能夠關聯多個
    q = models.UserInfo.objects.all().select_related('ut',)
    for row in q:
        print(row.name, row.ut.title)
    # prefetch_related 經過屢次單表查詢解決連表查詢效率低的問題
    # select * from userinfo;
    # Django內部:select * from usertype where id in [1,2,3]
    # Django將兩個結果集整合在一塊兒
    q = models.UserInfo.objects.all().prefetch_related('ut', )
    for row in q:
        print(row.name, row.ut.title)

    return HttpResponse('...')

1.2 多對多操做

app01.models.pyhtml

class Boy(models.Model):
    name = models.CharField(max_length=32)
    m = models.ManyToManyField('Girl')  # 多對多


class Girl(models.Model):
    nick = models.CharField(max_length=32)


# class Love(models.Model):
#     b = models.ForeignKey('Boy')
#     g = models.ForeignKey('Girl')
#     class Meta:
#         unique_together = [    # 聯合惟一索引
#             ('b', 'g')
#         ]

app01.views.pyjquery

# 數據庫操做
from app01 import models


def test(request):
    # # select_related 自動關聯UserType表(inner join),能夠關聯多個
    # q = models.UserInfo.objects.all().select_related('ut',)
    # for row in q:
    #     print(row.name, row.ut.title)
    # # prefetch_related 經過屢次單表查詢解決連表查詢效率低的問題
    # # select * from userinfo;
    # # Django內部:select * from usertype where id in [1,2,3]
    # # Django將兩個結果集整合在一塊兒
    # q = models.UserInfo.objects.all().prefetch_related('ut', )
    # for row in q:
    #     print(row.name, row.ut.title)

    # 多對多
    # objs1 = [
    #     models.Boy(name='溫豔傑'),
    #     models.Boy(name='楊振威'),
    #     models.Boy(name='蘇浩智'),
    #     models.Boy(name='鄒潤成'),
    # ]
    # models.Boy.objects.bulk_create(objs1, 10)
    # objs2 = [
    #     models.Girl(nick='李智'),
    #     models.Girl(nick='韓星宇'),
    #     models.Girl(nick='秦鎮'),
    #     models.Girl(nick='楊涵'),
    # ]
    # models.Girl.objects.bulk_create(objs2, 10)

    # models.Love.objects.create(b_id=1, g_id=1)
    # models.Love.objects.create(b_id=1, g_id=2)
    # models.Love.objects.create(b_id=2, g_id=4)
    # models.Love.objects.create(b_id=2, g_id=3)
    # models.Love.objects.create(b_id=3, g_id=3)
    # models.Love.objects.create(b_id=4, g_id=4)
    # models.Love.objects.create(b_id=4, g_id=2)

    # 1 和溫豔傑有關聯的姑娘的列表
    # 方法1:先找到該對象,而後經過反向操做獲取girl相關信息
    # obj = models.Boy.objects.filter(name='溫豔傑').first()
    # love_list = obj.love_set.all()
    # for row in love_list:
    #     print(row.g.nick)
    # 方法2: 遍歷時跨表
    # love_list = models.Love.objects.filter(b__name='溫豔傑')
    # for row in love_list:
    #     print(row.g.nick)
    # 方法3:values values_list
    # love_list = models.Love.objects.filter(b__name='溫豔傑').values('g__nick')
    # for item in love_list:
    #     print(item['g__nick'])
    # love_list = models.Love.objects.filter(b__name='溫豔傑').values_list('g__nick')
    # for item in love_list:
    #     print(item[0])
    # 方法4:select_related
    # love_list = models.Love.objects.filter(b__name='溫豔傑').select_related('g')
    # for obj in love_list:
    #     print(obj.g.nick)

    # 2 查看和韓星宇有關係的男生
    # 方法1:
    # obj = models.Girl.objects.filter(nick='韓星宇').first()
    # love_list = obj.love_set.all()
    # for row in love_list:
    #     print(row.b.name)
    # 方法2:
    # love_list = models.Love.objects.filter(g__nick='韓星宇')
    # for row in love_list:
    #     print(row.b.name)
    # 方法3:
    # love_list = models.Love.objects.filter(g__nick='韓星宇').values('b__name')
    # for item in love_list:
    #     print(item['b__name'])
    # love_list = models.Love.objects.filter(g__nick='韓星宇').values_list('b__name')
    # for item in love_list:
    #     print(item[0])
    # 方法4:
    # love_list = models.Love.objects.filter(g__nick='韓星宇').select_related('b')
    # for obj in love_list:
    #     print(obj.b.name)
    #

    # ManyToManyField 會生成app01_boy_m表,即boy和girl關係表
    # 正向操做
    obj = models.Boy.objects.filter(name='溫豔傑').first()
    print(obj.id, obj.name)
    # 往app01_boy_m添加與obj對象有關係的列
    # obj.m.add(3)     # 單值
    # obj.m.add(2, 4)  # 多值
    # obj.m.add(*[1,])   # 列表
    # 在關係表中刪除與obj對象有關係的列
    # obj.m.remove(1)
    # obj.m.remove(2, 4)
    # obj.m.remove(*[3])
    # 重置
    # obj.m.set([3, 1, ])
    # 獲取與obj有關係的女孩列表
    girl_list = obj.m.all().filter(nick='李智')  # q是girl對象
    for item in girl_list:
        print(item.nick)
    # 在關係表中刪除全部與obj有關係的列
    # obj.m.clear()

    # 反向操做:
    obj = models.Girl.objects.filter(nick='韓星宇').first()
    print(obj.id, obj.nick)
    v = obj.boy_set.all()  # boy對象
    print(v)

    return HttpResponse('...')

2 CSRF

給用戶生成一段隨機字符串,用戶提交數據時須要攜帶,不然返回403狀態碼,用於防範XSS攻擊ajax

<form action="/csrf1.html" method="post">
    {% csrf_token %}
    <input type="text">
    <input type="submit" value="提交">
</form>

不只會寫到form表單裏,cookie裏也會寫入數據庫

全站禁用django

# 'django.middleware.csrf.CsrfViewMiddleware',

局部禁用cookie

from django.views.decorators.csrf import csrf_exempt,csrf_protect

@csrf_exempt  # 局部禁用
def csrf1(request):
    if request.method == 'GET':
        return render(request, 'csrf1.html')
    else:
        return HttpResponse('...')

局部應用:app

from django.views.decorators.csrf import csrf_exempt,csrf_protect

@csrf_protect  # 局部使用
def csrf1(request):
    if request.method == 'GET':
        return render(request, 'csrf1.html')
    else:
        return HttpResponse('...')

2.1 ajax提交數據時攜帶CSRF

方法1:post

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/csrf1.html" method="post">
    {% csrf_token %}
    <input type="text" id="user">
    <input type="submit" value="提交">
    <input type="button" value="Ajax提交" onclick="submitForm();">
</form>
<script src="/static/jquery-3.2.1.min.js"></script>
<script>
    function submitForm() {
        var csrf = $('input[name=csrfmiddlewaretoken]').val();
        var user = $('#user').val();
        $.ajax({
            url:'csrf1.html',
            type: 'POST',
            data: {'user': user, 'csrfmiddlewaretoken': csrf},
            success:function (arg) {
                console.log(arg)
            }
        })
    }
</script>
</body>
</html>

方法2:fetch

function submitForm() {
        var token = $.cookie('csrftoken')
        var user = $('#user').val();
        $.ajax({
            url:'csrf1.html',
            type: 'POST',
            headers:{'X-CSRFToken': token},
            data: {'user': user},
            success:function (arg) {
                console.log(arg)
            }
        })
    }

3 CBV補充

CBV應用裝飾器(注:對於CSRF目前只能在類上加裝飾器)url

# 1.類上加裝飾器
@method_decorator(csrf_exempt,name='dispatch')
class Foo1(View):
    def get(self,request):
        pass
    def post(self,request):
        pass
# 2.指定方法上加
class Foo2(View):
    @method_decorator(wrapper)
    def get(self,request):
        pass
    def post(self,request):
        pass
相關文章
相關標籤/搜索