パートVI:Djangoのモデルレイヤ

ORMクエリ

1、限りオブジェクトは無制限に通話クエリセットオブジェクトクエリセットすることができよう。

res = models.User.objects.filter().filter().update()....

図2に示すように、限りオブジェクトがクエリセットのSQL文であるとして、次のステートメントを介して得ることができます。

print(res.query)

3、クエリセットでないオブジェクトは、SQL文で、パブリックメソッドを使用する必要性を得ることができた場合:

# 固定的日志文件配置 拷贝到配置文件中即可
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のテスト

ジャンゴをテストするとき、私たちはしばしばのみ、我々はテストスクリプトを書くことができますので、あまりにも、遅すぎる全体ジャンゴを開始し、いくつかの機能をテストする必要があります。

次のステップ:

1は、アプリ内で直接PYファイルを書き込む、またはするために、任意のディレクトリに作成tests.py次のコードファイルを書くこと:

# 以下代码可以去manage.py文件中复制
import os
 
 
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()

次のように2、デモは、例えば、Iは、テンプレート層をテストしたいと思い、コードは次のとおりです。

import os
 
 
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()
    # 导入models
    from app01 import models
    # 调用models相关功能
    models.Movie.objects.all()

単一テーブルのクエリ

テストしたモデルの時点で、我々は、関連するデータベース(settings.py)のパラメータと同様にして設定する必要があり__init__.py、輸入pymysqlを我々のモデルのmodels.pyファイルにテーブルを作成し、次の手順を実行します。

1、models.pyの表にモデルを作成

class Movie(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    # auto_now_add=True 当对数据进行创建的时候会自动添加时间
    publish_time = models.DateField(auto_now_add=True)

図2に示すように、移行データベースコマンド

python manage.py makemigrations
 
python manage.py migrate

16の基礎

  • 作成()の戻り値は、現在のデータオブジェクト自体に作成されます
  • すべて()クエリセットオブジェクト
  • フィルタ()クエリセットオブジェクト
  • 更新()更新データ
  • ()、削除データを削除
  • 最初の()最初のサブエレメントを取ります
  • 最後の()最後の子要素を取ります
  • 取得()データオブジェクト、お勧めできませんが、何の直接のエラーはありません提供しました
  • 値()クエリセットオブジェクトが表示されます:リストセット辞書
  • タプルのセットリスト:values_list()クエリセットオブジェクトが表示されるまで
  • ORDER_BY()ソートします
  • カウント)(カウント
  • フィールドを除外するために)(除外
  • データがあるかどうか()判定結果が存在し、戻り値はブール値であります
  • リバース()リバース
  • 重複排除)(DISTINCT、重複データが完全でなければなりません
from django.test import TestCase
 
# Create your tests here.
 
import os
 
 
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mystile.settings")
    import django
    django.setup()
    from test_func import models
    from datetime import date
    ctime = date.today()
    # 还可以直接传入日期时间对象
    # 1、create() 创建数据,得到的返回值就是创建数据的对象本身,可以直接使用res
    res = models.Movie.objects.create(title='山楂树之恋', price=999, publish_time=ctime)
 
    # 2、all()  查询表中的所数据,返回的是queryset对象, 类似列表套对象
    res = models.Movie.objects.all()
    print(res)
 
    # 3、filter() 按照指定条件去查询,返回的是queryset对象,类似列表套对象
    res = models.Movie.objects.filter(id=1)
    print(res)
 
    # 只要是queryset对象,就可以通过 点query 的方式查看sql语句
    res = models.Movie.objects.filter(title='山楂树之恋')
    print(res.query)
 
    # 4、get()  返回的是对象本身,不推荐使用,因为当查询条件不存在的时候会报错
    res = models.Movie.objects.get(pk=1)
    print(res)
 
    # 5、values() 获取指定字段对应的数据,列表套字典     QuerySet对象
    res = models.Movie.objects.values('title', 'price', 'publish_time')
    print(res)
 
    # 6、values_list() 获取指定字段对应的数据,元组套字典   QuerySet对象
    res = models.Movie.objects.values_list('title', 'price')
    print(res)
 
    # 7、first()  获取第一个元素对象,返回的是数据对象
    res = models.Movie.objects.filter().first()
    print(res)
 
    # 8、last()  获取最后一个元素对象,返回的是数据对象
    res = models.Movie.objects.filter().last()
    print(res.title)
 
    # 9、update()  更新数据    返回值是受影响的行数
    res = models.Movie.objects.filter(pk=2).update(title='大鱼海棠')
    print(res)
 
    # 10、delete()  删除数据     返回值(1, {'app01.Movie': 1})  受影响的表及行数
    res = models.Movie.objects.filter(pk=2).delete()
    print(res)
 
    # 11、count()  统计数据条数
    res = models.Movie.objects.count()
    print(res)
    res = models.Movie.objects.filter(pk=2).count()
    print(res)
 
    # 12、order_by()  按照指定字段排序
    res = models.Movie.objects.order_by('price')  # 默认升序
    res1 = models.Movie.objects.order_by('-price')  # 降序
    print(res)
    print(res1)
 
    # 13、exclude()  排除什么什么之外的数据
    res = models.Movie.objects.exclude(pk=1).first()
    print(res.title)
 
    # 14、exists()  判断查询是够有数据,返回bool值
    res = models.Movie.objects.filter(pk=10000).exists()
    print(res)
 
    # 15、reverse()  反转
    res = models.Movie.objects.order_by('price').reverse()
    print(res)
 
    # 16、distinct()  去重:去重的前提,必须是由完全一样的数据才能去重
    # 因此,这里要注意将django自动创建的主键排除在外
    res = models.Movie.objects.values('title', 'price').distinct()
    print(res)

二重下線問い合わせ

  • __gtより大きい
  • __lt未満
  • 以上__gte
  • 以下__lte
  • __in 或
  • 範囲内__Range、グーグーテールヘッドがあります

ファジィクエリ:

  • __大文字と小文字が区別が含まれています
  • __icontainsは、ケースを無視します

年月日:

  • create_time__year
  • create_time__month

一般的に括弧で使用ダブル下線クエリは、このような商品価格を求めるなどのデータをさらに制限は、200以上であります...

    # 双下划线查询
    # 1、查询价格大于200的电影
    res = models.Movie.objects.filter(price__gt=200)
    print(res)
 
    # 2、查询价格小于500的电影
    res = models.Movie.objects.filter(price__lt=500)
    print(res)
 
    # 3、查询价格大于等于200的电影
    res = models.Movie.objects.filter(price__gte=200)
    print(res)
 
    # 4、查询价格小于等于400的电影
    res = models.Movie.objects.filter(price__lte=500)
    print(res)
 
    # 5、查询价格在200到500之间的电影, 包括200到500
    res = models.Movie.objects.filter(price__in=(200, 500))
 
    # 6、查询价格是100,或66,或521
    res = models.Movie.objects.filter(price__in=[100, 66, 521])
 
    # 7、查询电影名字中包含字符“山楂树”的电影
    '''
    模糊查询:
        关键字:like
        关键符:%和-
    '''
    res = models.Movie.objects.filter(title__contains='山楂树')  # 区分大小写
    res = models.Movie.objects.filter(title__icontains='山楂树')  # 多加i可以忽略大小写
    print(res)
 
    # 8、查询2020年出版的电影
    res = models.Movie.objects.filter(publish_time__year=2020)
    print(res)
 
    # 9、查询是1月份出版的电影
    res = models.Movie.objects.filter(publish_time__month=1)
    print(res)

マルチテーブルクエリ

テーブルを作成するためのライブラリ管理システム

マルチテーブルクエリの場合、私たちは、次の手順を実行し、複数のテーブルを追加する必要があります。

モデルのテーブルに作成1、models.py

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    # 该字段新增数据自动添加 无需考虑
    publish_time = models.DateField(auto_now_add=True)
 
    # 出版社   一对多(一个出版社可以出版多个书,一本书不可以被多个出版社出版)   外键字段建在多的一方
    publish = models.ForeignKey(to='Publish')
 
    # 作者 多对多关系
    # 一本书可以有多个作者,一个作者也可以写多本书
    authors = models.ManyToManyField(to='Author')
 
 
class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=255)
 
 
class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
 
    # 作者详情  一对一关系
    author_detail = models.OneToOneField(to='AuthorDetail')
 
 
class AuthorDetail(models.Model):
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=255)

図2に示すように、データベース・マイグレーション・コマンドを実行します

python manage.py makemigrations
 
python manage.py migrate

削除の外部キーフィールドを変更して再検索

多くの

  • データ転送オブジェクトを公開
  • publish_id下りデータ主キー値
# 1、增 直接写实际的表字段 publish_id
    models.Book.objects.create(title='三国演义', price=123.23, publish_id=2)
    # 2、增 先查出来要绑定的出版社对象
    publish_obj = models.Publish.objects.get(pk=1)
    # 将查出来的对象赋值给publish
    models.Book.objects.create(title='水浒传', price=66.6, publish=publish_obj)
 
    # 查
    # 在下面的多表查询中
 
    # 改
    # 第一种方法
    models.Book.objects.filter(pk=2).update(publish_id=3)
    # 第二种方法,依旧是拿对象赋值
    publish_obj = models.Publish.objects.get(pk=3)
    models.Book.objects.filter(pk=2).update(publish=publish_obj)
 
    # 删
    '''
    外键字段在1.X版本中默认就是级联更新级联删除的
    2.X版本中,则需要你自己手动指定
        百度一大堆
    当没有级联删除和级联更新的情况下,只有删除关联表中的数据,才能删除和修改被关联表中的数据
    当有级联删除和级联更新的情况下,修改和删除被关联表中的数据, 关联表中的数据也会跟着被删除和修改
    '''

多くの多くの

追加()

あなたは、括弧内の数字を転送することができ、また摩耗のオブジェクトにすることができ、複数のパスをサポートし、第3の仮想表データに多くの多様性を追加するために、特別な追加。

  # 多对多
    # 1、给书籍绑定作者关系  add
    book_obj = models.Book.objects.filter(pk=2).first()
    # 书籍和作者的关系是由第三张表决定,那就意味着需要操作第三张表
    print(book_obj.authors)  # 书籍对象.虚拟字段authors就类似已经跨到了书籍和作者的第三张表
    book_obj.authors.add(1)  # 给书籍绑定一个主键为1的作者
    book_obj.authors.add(2, 3)
 
    # 第二种方法,直接添加对象
    book_obj = models.Book.objects.filter(pk=3).first()
    author_obj = models.Author.objects.get(pk=1)
    author_obj1 = models.Author.objects.get(pk=3)
    book_obj.authors.add(author_obj)
    book_obj.authors.add(author_obj, author_obj1)

削除する()

具体的には第三のリレーショナルテーブルにデータを削除し、いずれかのデジタル伝送はまた、括弧内のオブジェクトを渡すことができ、

そして、複数のパスをサポートしています。

    book_obj = models.Book.objects.filter(pk=3).first()
    book_obj.authors.remove(1)
    book_obj.authors.remove(2, 3)
 
    author_obj = models.Author.objects.get(pk=1)
    author_obj1 = models.Author.objects.get(pk=3)
    book_obj.authors.remove(author_obj)
    book_obj.authors.remove(author_obj, author_obj1)

セットする()

書籍や著者との関係を変更します

反復可能であることをデジタル括弧内のオブジェクトが、ニーズをサポートして転送します

    book_obj = models.Book.objects.filter(pk=3).first()
    book_obj.authors.set((3,))
    book_obj.authors.set((1, 2))
    authors_obj = models.Author.objects.get(pk=1)
    authors_obj1 = models.Author.objects.get(pk=2)
    book_obj.authors.set((authors_obj,))
    book_obj.authors.set([authors_obj, authors_obj1])

晴れ()

クリア関係

これは、任意のパラメータを必要としません。

    book_obj = models.Book.objects.filter(pk=3).first()
    book_obj.authors.clear()  # 去第三张表中清空书籍为1的所有书籍

クロステーブルのクエリ

ウェイクロスのテーブルのクエリ

1、サブクエリ

クエリ別のテーブルのテーブルとしてクエリ結果

2、クエリリスト

  • インナーには参加します
  • 左結合します
  • 右に参加
  • 連合

勧告:DOは文は、SQL ORM文または文を書き終えている一度は考えられない、捜査を少し書き、少し書かなければなりません

正と負の概念

フォワード:

クロステーブルクエリの外部キーフィールドは、リレーショナルテーブルにはフォワードと呼ばれる別のクエリ場合、現在のデータ・オブジェクトであるとき、

リバース:

コールは逆転されていない場合

式:

外部キーフィールドによって前方問い合わせ

小文字のテーブル名で検索リバース

オブジェクトに基づいてクロステーブルクエリ(サブクエリ)

ときに必要なときに複数のデータに対応する外部キーフィールドを追加することができるフォワード・クエリ、.all()

そうでない場合、外部キーポイントは、対応する辞書データオブジェクトを取得します

    # 1、查询书籍pk为1的出版社名称
    book_obj = models.Book.objects.filter(pk=2).first()
    print(book_obj.publish)
    print(book_obj.publish.name)
    print(book_obj.publish.addr)
 
    # 2、查询书籍pk为2的所有作者的姓名
    book_obj = models.Book.objects.filter(pk=3).first()
    print(book_obj.authors)  # test_func.Author.None
    print(book_obj.authors.all())
    author_list = book_obj.authors.all()
    for author_obj in author_list:
        print(author_obj.name)
 
    # 3、查询作者pk为1的电话号码
    author_obj = models.Author.objects.filter(pk=1).first()
    print(author_obj.author_detail)
    print(author_obj.author_detail.phone)
    print(author_obj.author_detail.addr)

小文字のオブジェクトに拠点を逆引きテーブル名は増やす必要があります_set.all()

  • 追加する多対と多くの時間が必要
  • 一つは必要ありません。
    # 4、查询出版社名称为东方出版社出版过的书籍
    publish_obj = models.Publish.objects.filter(name='东方出版社').first()
    print(publish_obj.book_set)  # test_func.Book.None
    print(publish_obj.book_set.all())
 
    # 5、查询作者为engon写过的书
    author_obj = models.Author.objects.filter(name='engon').first()
    print(author_obj.book_set)  # app01.Book.None
    print(author_obj.book_set.all())
 
    # 6、查询手机号为120的作者姓名
    author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
    print(author_detail_obj.author)
    print(author_detail_obj.author.name)
    print(author_detail_obj.author.age)

二重下線のクロステーブル・クエリ(クエリリスト)に基づいて、

長いテーブル間の関係があるとして、あなたは小文字のテーブル名の外部キーフィールド、連続クロステーブルクエリを転送するか、逆にすることができます

フォワード照会:第1捕捉対象の外部キーフィールド、オブジェクト内の値の外部キーフィールドを使用して、__値の別のテーブルに

逆引き:別のテーブルに、フィールドは、テーブル小文字のテーブル名の更なる制限を与えるために増加される括弧内.VALUE、本に直接採取してもよい__、フィルタブラケット内の別のテーブルにオブジェクトを取得しますオブジェクト値によって双下划线__値が別のテーブルに1をとります。

    # 1、查询书籍pk为2的出版社名称
    # 正向
    # 写外键字段,就意味着你已经在外键字段管理的那张表中
    res = models.Book.objects.filter(pk=2).values('publish__name')
    print(res)
    # 反向
    # 拿出版过pk为1的书籍对应的出版社
    res = models.Publish.objects.filter(book__pk=2)
    res = models.Publish.objects.filter(book__pk=2).values('name')
    print(res)
 
    # 2、查询书籍pk为2的作者姓名和年龄
    # 正向
    res = models.Book.objects.filter(pk=3).values('title', 'authors__name', 'authors__age')
    print(res)
    # 反向
    res = models.Author.objects.filter(book__pk=2)  # 拿出出版过书籍pk为1的作者
    res = models.Author.objects.filter(book__pk=2).values('name', 'age', 'book__title')
    print(res)
 
    # 3、查询作者是engon的年龄和手机号
    # 正向
    res = models.Author.objects.filter(name='engon').values('age', 'author_detail__phone')
    # 反向
    res = models.AuthorDetail.objects.filter(author__name='engon').values('author__age', 'phone')
    print(res)
 
    # 4、查询书籍pk为的2的作者的手机
    # 正向
    res = models.Book.objects.filter(pk=2).values('authors__author_detail__phone')
    print(res)
    # 反向
    res = models.AuthorDetail.objects.filter(author__book__pk=2).values('phone')
    print(res)

集計クエリ

キーワード:

aggregate

インポートモジュール:

from django.db.models import Max, Min, Avg, Count, Sum
  • マックスは、最大値を問い合わせます
  • 分の最小クエリ
  • 平均平均
  • 統計カウント
  • 合計合計

例:

     from django.db.models import Max, Min, Avg, Count, Sum
    # 查询所有书的平均价格
    res = models.Book.objects.aggregate(avg_num=Avg('price'))
    print(res)
    # 查询价格最贵的书籍
    res = models.Book.objects.aggregate(max_price=Max('price'))
    print(res)
    # 全部使用一遍
    res = models.Book.objects.aggregate(Avg('price'), Max('price'), Min('price'), Count('pk'), Sum('price'))
    print(res)

クエリをグループ化

キーワード:

annotate

輸入モジュール:

from django.db.models import Max,Min,Sum,Count,Avg
    # 1、统计每一本书的作者个数
    res = models.Book.objects.annotate(author_num=Count('authors')).values('title', 'author_num')
    print(res)
 
    # 2、统计出每一个出版社卖的最便宜的书的价格
    res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'book__title', 'book__price')
    print(res)
 
    # 3、统计不止一个作者的书
    res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title')
    print(res)
 
    # 4、查询各个作者出的书籍的总价格
    res = models.Author.objects.annotate(author_num=Sum('book__price')).values('name', 'author_num')
    print(res)
 
    # 5、如何按照表中的某一指定字段分组
    res = models.Book.objects.values('price').annotate()  # 以价格字段进行分组
    print(res)

FとQの問合せ

あなたはモジュールをインポートする必要があります

from django.db.models import F, Q

F

あなたは、フィールドに、テーブルの対応の値を取得することができます

1.查询库存数大于卖出数的书籍
res = models.Book.objects.filter(kucun__gt=F('maichu'))
print(res)
 
2.将所有书的价格提高100
res = models.Book.objects.update(price=F('price') + 100)

Q

条件は、クエリを変更することができます。

  • そして
  • 若しくは
  • ではありません
Q能够改变查询的条件关系  and or not
1.查询书的名字是python入门或者价格是1000的书籍
res = models.Book.objects.filter(title='python入门',price=1000)  # and关系
res = models.Book.objects.filter(Q(title='python入门'),Q(price=1000))  # 逗号是and关系
res = models.Book.objects.filter(Q(title='python入门')|Q(price=1000))  # |是or关系
res = models.Book.objects.filter(~Q(title='python入门')|Q(price=1000))  # ~是not关系

高次のQの使用状況

Qハイエンドの使用制限は、検索ボックスの機能のために多く、ユーザーが入力したクエリ文字列に変換することができます。

# res = models.Book.objects.filter('title'='python入门')
 
q = Q()
q.connector = 'or'  # q对象默认也是and关系  可以通过connector改变or
q.children.append(('title','python入门'))
q.children.append(('price',1000))
 
res = models.Book.objects.filter(q)
print(res)
 

一般的な分野で使用されるモデル

AutoField(primary_key=True)  主键字段
CharField(max_length=32)     varchar(32)
IntegerField()               int
BigIntergerField()           bigint
DecimalField()               decimal
EmailField()                 varchart(254)
DateField()                     date
DateTimeField()              datetime
    auto_now:每次编辑数据的时候都会自动更新该字段时间
    auto_now_add:创建数据的时候自动更新
BooleanField(Field)
    给该字段传布尔值 会对应成  数字0/1
    is_delete
    is_status
    is_vip
TextField(Field)
    - 文本类型
    存储大段文本
FileField(Field)
    - 字符串,路径保存在数据库,文件上传到指定目录,只存文件路径
    upload_to = '指定文件路径'
    给该字段传文件对象 文件会自动保存到upload_to指定的文件夹下 然后该字段存文件的路径

ジャンゴデフォルトの文字列型は、ビルドにvarchar型、char型のフィールドほしいですが構築されている次のように、あなたは、char型のカスタムフィールドを必要とします:

# modles.py
 
from django.db.models import Field
 
 
class RealCharField(Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length = max_length  # 拦截一个父类的方法 操作完之后 利用super调用父类的方法
        super().__init__(max_length=max_length,*args,**kwargs)
 
 
    def db_type(self, connection):
        return 'char(%s)'%self.max_length
 
 
# 使用自定义的char类型字段
class Movie(models.Model):
    textField = RealCharField(max_length=64)

フィールド内の重要なパラメータ

ヌル

nullは空にすることができ、フィールドを表すために使用されます

デフォルト

デフォルトでは、このフィールドのデフォルト値を設定します

ユニーク

この表のユニーク= Trueのフィールドへのセットは一意である必要があります。

db_index

db_index場合= Trueの場合、インデックスフィールドは、この目的のために設定されている表します。

2.xのバージョンカスケード更新やカスケード削除

ジャンゴ1.1は、デフォルトのカスケード削除カスケード更新を手動でdjango2.x指定する必要があります

on_delete = models.CASCADE

db_contraints =真

  • DELETE CASCADE:models.CASCADE
    データ関連テーブルを削除する場合、外部キーも削除されます
  • ブランク:models.SET_NULL
    データ削除関連テーブル、外部キーブランクは、もちろん、あなたが外部キーフィールドが空で許可する必要があり、ヌル=真を
  • 設定既定値:models.SET_DEFAULT
    外部キーときの注意に加えて、デフォルト値を定義して、デフォルト値に、外部キーフィールドセットを削除しました。
#级联删除情况
class UserToken(models):                             #级联删除,用户删除,它也删除
    user = models.OneToOneField(to='User', on_delete=models.CASCADE, to_field='id')
    token = models.CharField(max_length=128, null=True)
 
 
#置空情况
class Server(models.Model):
 
    server_type_choice = (
        (1, "WEB"),
        (2, "存储"),
        (3, "缓存")
    )
 
    server_type = models.IntegerField(choices=server_type_choice)
    hostname = models.CharField(max_length=32)
    port = models.IntegerField()
    business_unit = models.ForeignKey("BusinessUnit", on_delete= models.SET_NULL, null=True)
 
 
#设置默认值
    user = models.ForeignKey("UserInfo", on_delete= models.SET_DEFAULT, default=0)
  • 珍しい二
  • PROTECT:オプションは、時間を削除する場合は保護モードは、ProtectedErrorエラーがスローされます。
  • SET():コースのカスタム値は、対応する物理的です

パラメータの選択

あなたはデータではなく、文字列のデータベースに保存されている番号で、パラメータの選択肢を使用することを検討して、完全にすることができ含まれている場合、ディスクスペースを節約することができます。

class Userinfo(models.Model):
    username = models.CharField(max_length=32)
    gender_choices = (
        (1,'男'),
        (2,'女'),
        (3,'其他'),
    )
    gender = models.IntegerField(choices=gender_choices)
    # 该字段还是存数字 并且可以匹配关系之外的数字
    record_choices = (('checked', "已签到"),
          ('vacate', "请假"),
          ('late', "迟到"),
          ('noshow', "缺勤"),
          ('leave_early', "早退"),
          )
 
    record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)
 
 
user_obj = models.Userinfo.objects.get(pk=1)
print(user_obj.username)
print(user_obj.gender)
# 针对choices参数字段 取值的时候   get_xxx_display()
print(user_obj.get_gender_display())
# 针对没有注释信息的数据  get_xxx_display()获取到的还是数字本身
user_obj = models.Userinfo.objects.get(pk=4)
print(user_obj.gender)
print(user_obj.get_gender_display())

データベースのクエリの最適化

すべてのクエリジャンゴORMある不活性クエリのような手段が、結果からSQL文をチェックを使用していないと実行されません、、:

res = models.Book.objects.all()

私が使用して解像度を参照していない場合は、このステートメントは実行されません。

のみ与延期

唯一の役割:

ブラケットは、フィールドを渡し、結果は括弧内に指定された唯一のフィールド属性が含まれているデータオブジェクトのセットのリストであり、

オブジェクトフィールドのプロパティのポイントは、データベースになりませんが、あなたは非カッコ内のフィールドを指して一度データを取得することができますが、それはデータベースクエリを行きます

物体視野点の括弧内のオブジェクトに割り当てられているカッコ内の唯一のフィールドの結果が行くようにデータベースを照会し、その後、括弧内のフィールドを越えて、データベースクエリを取ることはありません。

res = models.Book.objects.only('title')  # 這些對象内部只有title屬性
# print(res)
for r in res:
    # print(r.title)
    print(r.price)

延期アクション:

カッコ内のフィールドのパス、結果はデー​​タオブジェクトのセットのリストで、物点クエリ延期ブラケット、行くためのフィールド属性複製データベース内のフィールド属性が、クエリフィールド延期ブラケットには、データベースを取ることはありませんありません。

res = models.Book.objects.defer('title')
for r in res:
    print(r.title)

selected_related:

インテリアは、すべて一緒に接続された第一のテーブルにも手術台で、すべてがAにパッケージするので、そのオブジェクトへのパッケージうち1回のチェックの後、オブジェクトは、時間の任意のテーブルにデータを取得するために、データベース内のデータの後に歩く必要はありません。オブジェクトのプロパティ。

Select_relatedブラケットは、外部キーフィールドを送ることができ、かつ現場の多くのことができない、と多くは一つだけです

select_related(外键字段1__外键字段2__外键字段3.....)

res = models.Book.objects.select_related('authors')
for r in res:
    print(r.publish.name)
    print(r.publish.addr)

prefetch_related

テーブルの現在のポイントの外部キー・フィールドがあまりにも行く必要はありません後であっても、テーブルのように見えるが、内部サブクエリを操作し、サブクエリは、すべての内部のデータがテーブルオブジェクトへの外部キーを封入し、またはオブジェクトテーブルデータベース。

prefetch_related
res = models.Book.objects.prefetch_related('publish')
# print(res)
 
for r in res:
    print(r.publish.name)

長所と短所:

一度だけでも動作し、テーブル、SQLクエリのテイク利点をselect_relatedが、欠点は、時間がかかり、動作可能に接続テーブルです。

prefetch_relatedサブクエリは、時間がかかり、クエリの数に、2つのSQLクエリを取ります。

どのようにDjangoのORMオープントランザクション操作

サービス導入

トランザクション(ACID)の4つの特徴:

アトミック:Aのトランザクションは、作業の不可分の単位で、トランザクションのすべての操作が正常に実行され、トランザクション全体が成功するには、限り、任意のSQLステートメントが失敗したとして、それは、トランザクションを実行する前の状態にフォールバックします。

一貫性:トランザクションが一貫していなければならない前と後のデータの整合性、こうした銀行振り込みなどは、乙がお金を転送し、関係なく、トランザクションの成功または失敗の、トランザクションの終了後に2000元の両方の総預金のことを確認する必要があります。

アイソレーション:別のオペレーションが同じデータトランザクションを同時に、並行環境を指し、各トランザクションは、独自のデータ空間の完全なを持っています

永続性:長いデータベース内のデータの変化は永久的である限り、取引の成功裡の妥結を指します。

# django orm开启事务操作
    from django.db import transaction
    with transaction.atomic():
        # 在with代码块中执行的orm语句同属于一个事务
        pass
 
    # 代码块运行结束 事务就结束了  事务相关的其他配置 你可以百度搜搜看

3つのデータベース設計パラダイム:

最初のパラダイム:原子の性質を必要としていた、もはや打破することができます。

最初のパラダイムの例を満たしていません。

第二のパラダイム:2NFは一部依存不在記録に固有のユニークな識別が記録される必要があり、すなわち一意のエンティティ、すなわち。

表:学生番号、コース番号、名前、クレジット;

この表は明らかに二つのトランザクションを示しています。学生情報、コース情報、非プライマリキーフィールドのためには、主キーに依存しなければならないコースの数に依存信用名前と依存学生の数が、それは2つのパラダイムを満たしていません。

問題がある可能性があります。

  • 数据冗余:各レコードには、同じ情報が含まれています。
  • 删除异常:すべての生徒の学力を削除し、我々は情報が削除されたフルコースを置きます。
  • 插入异常:学生数ではなく、データベースに記録することはできません。
  • 更新异常:単位時間、すべての行の調整を調整します。

正しいアプローチ:
学生:Student(学生ID、名前);
コース:Course(コース番号、クレジット);
選択科目の関係:StudentCourse(学生番号、コース番号、結果)。

第三のパラダイム:3NFフィールドはれる冗余性任意のフィールドに必要な他のフィールドに由来することができない、それは冗長なフィールド、すなわち、転写依存性が存在しないことを必要としません。

表:学生ID、氏名、年齢、大学の名前、大学の電話

あるので、推移依存関係(学生証)→(学生)→(アカデミー)→(大学の電話が):。

問題がある可能性があります。

  • 数据冗余:重複した値;
  • 更新异常:冗長な情報を複製し、あなたが変更の時に多数のレコードを変更する必要があり、存在することになるデータの不整合

正しいアプローチ:

:(学校の学生番号、氏名、年齢、大学);

学校:(カレッジ、携帯電話)。

パラダイムデザインと抗設計パラダイムの長所と短所:

パラダイム

利点:

  • あなたはデータの冗長性を削減しようとすることができ、高速なデータテーブル更新小さな
  • より高速な抗正規化より更新のパラダイム
  • パラダイムテーブルは、抗正規よりも一般に小さいです

短所:

  • クエリではパフォーマンスの低下が生じ、アソシエイトに複数のテーブルが必要です
  • インデックスの最適化することがより困難に

アンチ正規化

利点:

  • 関連するテーブルを減らすことができます
  • これは、最適化インデックスをより良くすることができます

短所:

  • 異常なデータの冗長性とデータのメンテナンスの存在
  • データへの変更は、より高価です

オープン取引方法をDjangoの

# django orm开启事务操作
from django.db import transaction
with transaction.atomic():
    # 在with代码块中执行的orm语句同属于一个事务
    pass
 
# 代码块运行结束 事务就结束了  事务相关的其他配置 你可以百度搜搜看

MTVとMVCモデル

知られているMTV MTV Djangoフレームワーク
M:モデル
T:テンプレート
Vは:ビュー
MVC
Mを:モデル
V:ビュー
contronnarコントローラ(経路分布urls.py):C
エッセンス:MTVも本質的にMVCを

おすすめ

転載: www.cnblogs.com/cnhyk/p/12173537.html