Django雜記

Django ORM執行原生SQL

# extra
# 在QuerySet的基礎上繼續執行子語句
# extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)

# select和select_params是一組,where和params是一組,tables用來設置from哪一個表
# Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
# Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
# Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
# Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

舉個例子:
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
# 更高靈活度的方式執行原生SQL語句
# from django.db import connection, connections
# cursor = connection.cursor()  # cursor = connections['default'].cursor()
# cursor.execute("""SELECT * from auth_user where id = %s""", [1])
# row = cursor.fetchone()

ORM 執行原生SQL的方法

Django終端打印SQL語句

在Django項目的settings.py文件中,在最後複製粘貼以下代碼:python

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

即爲你的Django項目配置上一個名爲django.db.backends的logger實例便可查看翻譯後的SQL語句。 git

在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)

多對多的三種方式

多對多的方式:
1. ORM自動幫我建立第三張表django

models.ManyToManyField(to="Book", related_name="authors")

2. 本身建立第三張表, 利用外鍵分別關聯做者和書瀏覽器

# 書
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()

    def __str__(self):
        return self.name


# 本身動手 建立做者和書關聯的第三張表
# 此時 在ORM層面 做者和書就沒有多對多的關係了
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")

  關聯查詢比較麻煩,由於沒辦法使用ORM提供的便利方法app

3. 本身建立第三張表,使用ORM 的ManyToManyFiled()fetch

from django.db import models

# Create your models here.


from django.db import models

# Create your models here.
from django.db import models

# Create your models here.


# 出版社
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()
    # 經過through,告訴Django經過哪張表創建關係,through_fields來指定使用我建立的第三張表來構建多對多的關係
    books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book",))
    # 第一個字段: 多對多設置在哪一張表裏, 第三張表經過什麼字段找到這張表(Author) 就把這個字段寫在前面
    detail = models.OneToOneField(to="AuthorDetail")

    def __str__(self):
        return self.name


# 本身動手 建立做者和書關聯的第三張表
# 此時 在ORM層面
class Author2Book(models.Model):
    id = models.AutoField(primary_key=True)
    # 做者id
    author = models.ForeignKey(to="Author")
    # 書id
    book = models.ForeignKey(to="Book")

    # memo
    memo = models.CharField(max_length=64, null=True)

    class Meta:
        # 創建惟一約束
        unique_together = ("author", "book")


# 做者詳情
class AuthorDetail(models.Model):
    # 愛好
    hobby = models.CharField(max_length=32)
    # 地址
    addr = models.CharField(max_length=128)

  使用此種方式建立多對多表的時候,沒有 add() remove() 等方法網站

咱們應該用哪一種?
看狀況:
1. 若是你第三張表沒有額外的字段,就用第一種
2. 若是你第三張表有額外的字段,就用第三種或第一種spa

csrf簡單用法

什麼是CSRF ————跨站請求僞造
問題:
1. 釣魚網站的頁面和正經網站的頁面對瀏覽器來講有什麼區別? (頁面是怎麼來的?)
釣魚網站的頁面是由 釣魚網站的服務端給你返回的
正經網站的網頁是由 正經網站的服務端給你返回的

2. Django中內置了一個專門處理csrf問題的中間件
django.middleware.csrf.CsrfViewMiddleware

這個中間件作的事情:
1. 在render返回頁面的時候,在頁面中塞了一個隱藏的input標籤
用法:
咱們在頁面上 form表單 裏面 寫上 {% csrf_token %}
<input type="hidden" name="csrfmiddlewaretoken" value="8gthvLKulM7pqulNl2q3u46v1oEbKG7BSwg6qsHBv4zf0zj0UcbQmpbAdijqyhfE">

2. 當你提交POST數據的時候,它幫你作校驗,若是校驗不經過就拒絕此次請求翻譯

相關文章
相關標籤/搜索