Django model selectの多種の用法の詳しい解
10175 ワード
「Django model updateの様々な使い方の紹介」では、Django modelの様々なupdate操作を紹介しています.この文章は彼女の姉妹編で、Django model selectの使い方を詳しく紹介しています.MySQLに対応したクエリー文を添えて、理解しやすいです.
きほんそうさ
一般的な操作
ステップアップオペレーション
時間フィールド
Qの使用
Qオブジェクトはキーワードパラメータをカプセル化することができ,複数のクエリーをよりよく適用し,&(and)、|(or)、~(not)オペレータを組み合わせることができる.
たとえば下の文
SQL文に変換するには、次のようにします.
select * from User where role like 'sre_%' and(name='公衆番号'or name='運維コーヒーバー')
通常、フロント検索ボックスに文字を入力したり、バックグラウンドでデータベースにタイトルやコンテンツを検索したりするなど、Qを検索ロジックとして使用します.
外部キー:ForeignKey
テーブル構造:
順方向クエリー:
#ユーザーのロール名を問い合わせる_t = User.objects.get(username='運維コーヒーバー')t.role.name
逆クエリー:
#クエリーロールの下に含まれるすべてのユーザー_t = Role.objects.get(name='Role03') _t.user_set.all()
別の逆クエリー方法:
_t = Role.objects.get(name='Role03')
前の方法よりsetのメソッドはクエリ速度が速くなります.objects.filter(role=_t)
3つ目の逆クエリの方法:
外部キーフィールドにrelated_がある場合nameプロパティ、たとえばmodelsは次のとおりです.
ではrelated_を直接使えますnameプロパティがロールに取得されたすべてのユーザー
_t = Role.objects.get(name = 'Role03') _t.roleUsers.all()
M2M:ManyToManyField
テーブル構造:
class Group(models.Model): name = models.CharField(max_length=16, unique=True)
class User(models.Model): username = models.CharField(max_length=255, unique=True) groups = models.ManyToManyField(Group, related_name='groupUsers')
順方向クエリー:
#ユーザーの所属グループを問い合わせる_t = User.objects.get(username='運維コーヒーバー')t.groups.all()
逆クエリー:
#クエリー・グループにユーザーが含まれています_t = Group.objects.get(name = 'groupC') _t.user_set.all()
同じM 2 Mフィールドにrelated_がある場合name属性は、下の方で直接チェックできます
_t = Group.objects.get(name = 'groupC') _t.groupUsers.all()
get_object_or_404
通常、データベースでデータを検索する場合は、次の方法を使用します.
_t = User.objects.get(id=734)
ただしid=724のデータが存在しない場合、プログラムはエラーを投げ出す
abcer.models.DoesNotExist: User matching query does not exist.
プログラムの互換性と異常判断のために、次の2つの方法を使用できます.
方法一:getをfilterに変更する
_t = User.objects.filter(id=724)#取り出し_t後に判断する_tが存在するかどうか
方法2:get_を使用するobject_or_404
from django.shortcuts import get_object_or_404
_t = get_object_or_404(User, id=724) # get_object_or_404メソッドは、djangoのgetメソッドを先に呼び出し、クエリのオブジェクトが存在しない場合、Http 404の例外を放出する
実装方法は、次のようになります.
名前の通り、オブジェクトが存在しない場合は、次のように作成されます.
object, created = User.objects.get_or_create(username='運維コーヒーバー')
objectとcreatedからなるメタグループを返します.objectはクエリーされたオブジェクトまたは作成されたオブジェクトであり、createdは新しいオブジェクトが作成されたかどうかを示すブール値です.
実装方法は、次のようになります.
オリジナルSQLの実行
Djangoの中でORMを使うことができるのはそれのORMを使うようにしましょう、原生のSQLを実行することを提案しないで、いくつか安全な問題があるかもしれなくて、もし本当にSQLが複雑すぎてORMが実現できないならば、それでは下で原生のSQLを実行する方法を見て、直接pymysqlを使うこととほぼ一致しました
注意ここの表の名前はapp名+下線+model名の方式を使います
きほんそうさ
# , SQL:select * from User
User.objects.all()
# , SQL:select * from User where name = ' '
User.objects.filter(name=' ')
# , SQL:select * from User where name != ' '
User.objects.exclude(name=' ')
# ( ,id ), SQL:select * from User where id = 724
User.objects.get(id=123)
一般的な操作
# , SQL:select count(1) from User
User.objects.count()
# , SQL:select count(1) from User where name = ' '
User.objects.filter(name=' ').count()
# ,>, SQL:select * from User where id > 724
User.objects.filter(id__gt=724)
# ,>=, SQL:select * from User where id >= 724
User.objects.filter(id__gte=724)
# , 1 and id < 10
User.objects.filter(id__gt=1, id__lt=10)
# ,in, SQL:select * from User where id in (11,22,33)
User.objects.filter(id__in=[11, 22, 33])
# ,not in, SQL:select * from User where id not in (11,22,33)
User.objects.exclude(id__in=[11, 22, 33])
# :isnull=True, SQL:select * from User where pub_date is null
User.objects.filter(pub_date__isnull=True)
# :isnull=False, SQL:select * from User where pub_date is not null
User.objects.filter(pub_date__isnull=True)
# ,like, , SQL:select * from User where name like '%sre%',SQL
User.objects.filter(name__contains="sre")
# ,like, , SQL:select * from User where name like '%sre%',SQL
User.objects.filter(name__icontains="sre")
# , , SQL:select * from User where name not like '%sre%',SQL
User.objects.exclude(name__contains="sre")
# , , SQL:select * from User where name not like '%sre%',SQL
User.objects.exclude(name__icontains="sre")
# ,between and, SQL:select * from User where id between 3 and 8
User.objects.filter(id__range=[3, 8])
# , , SQL:select * from User where name like 'sh%',SQL
User.objects.filter(name__startswith='sre')
# , , SQL:select * from User where name like 'sh%',SQL
User.objects.filter(name__istartswith='sre')
# , , SQL:select * from User where name like '%sre',SQL
User.objects.filter(name__endswith='sre')
# , , SQL:select * from User where name like '%sre',SQL
User.objects.filter(name__iendswith='sre')
# ,order by, , SQL:select * from User where name = ' ' order by id
User.objects.filter(name=' ').order_by('id')
# ,order by, name , name id
User.objects.filter(name=' ').order_by('name','-id')
# ,order by, , SQL:select * from User where name = ' ' order by id desc
User.objects.filter(name=' ').order_by('-id')
ステップアップオペレーション
# limit, SQL:select * from User limit 3;
User.objects.all()[:3]
# limit, , SQL, :select * from User limit 3,10000000, 3 , 10000000 (10000000 )
User.objects.all()[3:]
# offset, 10-20 ( 10, 20), SQL, SQL
User.objects.all()[10:20]
# ,group by, SQL:select username,count(1) from User group by username;
from django.db.models import Count
User.objects.values_list('username').annotate(Count('id'))
# distinct, SQL:select distinct(username) from User
User.objects.values('username').distinct().count()
# filter 、 , SQL:select username,fullname from accounts_user
User.objects.values_list('username', 'fullname')
# filter 、 , values_list , , , flat , ,
User.objects.values_list('username', flat=True)
# int 、 、 、
from django.db.models import Sum,Count,Max,Min,Avg
User.objects.aggregate(Count(‘id'))
User.objects.aggregate(Sum(‘age'))
時間フィールド
# ,date
User.objects.filter(create_time__date=datetime.date(2018, 8, 1))
User.objects.filter(create_time__date__gt=datetime.date(2018, 8, 2))
# ,year
User.objects.filter(create_time__year=2018)
User.objects.filter(create_time__year__gte=2018)
# ,month
User.objects.filter(create_time__month__gt=7)
User.objects.filter(create_time__month__gte=7)
# ,day
User.objects.filter(create_time__day=8)
User.objects.filter(create_time__day__gte=8)
# ,week_day
User.objects.filter(create_time__week_day=2)
User.objects.filter(create_time__week_day__gte=2)
# ,hour
User.objects.filter(create_time__hour=9)
User.objects.filter(create_time__hour__gte=9)
# ,minute
User.objects.filter(create_time__minute=15)
User.objects.filter(create_time__minute_gt=15)
# ,second
User.objects.filter(create_time__second=15)
User.objects.filter(create_time__second__gte=15)
#
today = datetime.date.today()
select = {'day': connection.ops.date_trunc_sql('day', 'create_time')}
deploy_date_count = Task.objects.filter(
create_time__range=(today - datetime.timedelta(days=7), today)
).extra(select=select).values('day').annotate(number=Count('id'))
Qの使用
Qオブジェクトはキーワードパラメータをカプセル化することができ,複数のクエリーをよりよく適用し,&(and)、|(or)、~(not)オペレータを組み合わせることができる.
たとえば下の文
from django.db.models import Q
User.objects.filter(
Q(role__startswith='sre_'),
Q(name=' ') | Q(name=' ')
)
SQL文に変換するには、次のようにします.
select * from User where role like 'sre_%' and(name='公衆番号'or name='運維コーヒーバー')
通常、フロント検索ボックスに文字を入力したり、バックグラウンドでデータベースにタイトルやコンテンツを検索したりするなど、Qを検索ロジックとして使用します.
_s = request.GET.get('search')
_t = Blog.objects.all()
if _s:
_t = _t.filter(
Q(title__icontains=_s) |
Q(content__icontains=_s)
)
return _t
外部キー:ForeignKey
テーブル構造:
class Role(models.Model):
name = models.CharField(max_length=16, unique=True)
class User(models.Model):
username = models.EmailField(max_length=255, unique=True)
role = models.ForeignKey(Role, on_delete=models.CASCADE)
順方向クエリー:
#ユーザーのロール名を問い合わせる_t = User.objects.get(username='運維コーヒーバー')t.role.name
逆クエリー:
#クエリーロールの下に含まれるすべてのユーザー_t = Role.objects.get(name='Role03') _t.user_set.all()
別の逆クエリー方法:
_t = Role.objects.get(name='Role03')
前の方法よりsetのメソッドはクエリ速度が速くなります.objects.filter(role=_t)
3つ目の逆クエリの方法:
外部キーフィールドにrelated_がある場合nameプロパティ、たとえばmodelsは次のとおりです.
class User(models.Model):
username = models.EmailField(max_length=255, unique=True)
role = models.ForeignKey(Role, on_delete=models.CASCADE,related_name='roleUsers')
ではrelated_を直接使えますnameプロパティがロールに取得されたすべてのユーザー
_t = Role.objects.get(name = 'Role03') _t.roleUsers.all()
M2M:ManyToManyField
テーブル構造:
class Group(models.Model): name = models.CharField(max_length=16, unique=True)
class User(models.Model): username = models.CharField(max_length=255, unique=True) groups = models.ManyToManyField(Group, related_name='groupUsers')
順方向クエリー:
#ユーザーの所属グループを問い合わせる_t = User.objects.get(username='運維コーヒーバー')t.groups.all()
逆クエリー:
#クエリー・グループにユーザーが含まれています_t = Group.objects.get(name = 'groupC') _t.user_set.all()
同じM 2 Mフィールドにrelated_がある場合name属性は、下の方で直接チェックできます
_t = Group.objects.get(name = 'groupC') _t.groupUsers.all()
get_object_or_404
通常、データベースでデータを検索する場合は、次の方法を使用します.
_t = User.objects.get(id=734)
ただしid=724のデータが存在しない場合、プログラムはエラーを投げ出す
abcer.models.DoesNotExist: User matching query does not exist.
プログラムの互換性と異常判断のために、次の2つの方法を使用できます.
方法一:getをfilterに変更する
_t = User.objects.filter(id=724)#取り出し_t後に判断する_tが存在するかどうか
方法2:get_を使用するobject_or_404
from django.shortcuts import get_object_or_404
_t = get_object_or_404(User, id=724) # get_object_or_404メソッドは、djangoのgetメソッドを先に呼び出し、クエリのオブジェクトが存在しない場合、Http 404の例外を放出する
実装方法は、次のようになります.
from django.http import Http404
try:
_t = User.objects.get(id=724)
except User.DoesNotExist:
raise Http404
get_or_create
名前の通り、オブジェクトが存在しない場合は、次のように作成されます.
object, created = User.objects.get_or_create(username='運維コーヒーバー')
objectとcreatedからなるメタグループを返します.objectはクエリーされたオブジェクトまたは作成されたオブジェクトであり、createdは新しいオブジェクトが作成されたかどうかを示すブール値です.
実装方法は、次のようになります.
try:
object = User.objects.get(username=' ')
created = False
exception User.DoesNoExist:
object = User(username=' ')
object.save()
created = True
returen object, created
オリジナルSQLの実行
Djangoの中でORMを使うことができるのはそれのORMを使うようにしましょう、原生のSQLを実行することを提案しないで、いくつか安全な問題があるかもしれなくて、もし本当にSQLが複雑すぎてORMが実現できないならば、それでは下で原生のSQLを実行する方法を見て、直接pymysqlを使うこととほぼ一致しました
from django.db import connection
with connection.cursor() as cursor:
cursor.execute('select * from accounts_User')
row = cursor.fetchall()
return row
注意ここの表の名前はapp名+下線+model名の方式を使います