Django多層ネストManyToManyフィールドORM操作詳細
4968 ワード
djangoでプロジェクトを書く時、多くのシーンに出会いました。ORM操作についてデータを取得しましたが、説明しにくいです。Baiduの検索キーワードはどのように検索すればいいのか分かりません。ここで問題を細かくして、シーンを復元して、踏みつけた穴を記録します。
まずモデルを挙げます。生活の中の例を挙げて、問題を理解しやすいです。
つまりbookとchapterは多対多で、chapterとproblemも多対多です。
場面一:書籍の下のすべての練習問題
book.chapter.filteris_pass=True).count()
場面三:ある問題がこの本の中にあるかどうかを判断する
究極のモデル
モデルクラスは次の通りです。私はclass Metaにordeng='-date_を設置しました。create''とは、モデルオブジェクトが返した記録結果セットをこのフィールドで並べ替えます。
distinctを使うのは上の状況と似ていますので、載せません。
以上のこのDjango多層ネストされたManyToManyフィールドORMの操作の詳細は、小編集が皆さんに提供している内容の全てです。参考にしていただければ幸いです。どうぞよろしくお願いします。
まずモデルを挙げます。生活の中の例を挙げて、問題を理解しやすいです。
#
class Problem(models.Model):
desc = models.CharField()
answer = models.TextField()
is_pass = models.BooleanField(default=False, verbose_name=" ")
#
class Chapter(models.Model):
_id = models.IntegerField(verbose_name=" ")
title = models.CharField()
problem = models.ManyToManyField(Problem)
pass_rate = models.IntegerField(verbose_name=" ")
#
class Book(models.Model):
title = models.CharField()
desc = models.TextField()
chapter = models.ManyToManyField(Chapter,verbose_name=" ")
speed = models.IntegerField(verbose_name=" ", default=0)
数学の本だと仮定して、5つの章があります。各章には数の異なる練習問題があります。つまりbookとchapterは多対多で、chapterとproblemも多対多です。
場面一:書籍の下のすべての練習問題
#
# , , ( )
book.chapter.filter(problem___id__isnull=False).count()
場面二:書籍の下で通過する練習問題book.chapter.filteris_pass=True).count()
場面三:ある問題がこの本の中にあるかどうかを判断する
def problem_in_ladder(book, problem):
for i in book.chapter.all():
if problem in i.problem.all():
return True
return False
できるだけviewでmodelsの値を取る操作を減らすために、上記のいくつかのシーンの方法をmodelsの種類に書いてください。究極のモデル
#
class Problem(models.Model):
desc = models.CharField()
answer = models.TextField()
is_pass = models.BooleanField(default=False, verbose_name=" ")
#
class Chapter(models.Model):
_id = models.IntegerField(verbose_name=" ")
title = models.CharField()
problem = models.ManyToManyField(Problem)
pass_rate = models.IntegerField(verbose_name=" ")
@property
def items(self):
return self.problem.count()
@property
def pass_problem(self):
return self.problem.filter(is_pass=True).count()
#
class Book(models.Model):
title = models.CharField()
desc = models.TextField()
chapter = models.ManyToManyField(Chapter,verbose_name=" ")
speed = models.IntegerField(verbose_name=" ", default=0)
@property
def chapters(self):
return self.chapter.count()
@property
def pass_count(self):
return self.chapter.filter(problem__is_pass=True).count()
@property
def items(self):
return self.chapter.filter(problem___id__isnull=False).count()
知識を補充します:djangoの中でmodelがordengを設置した後に、distinct()とannotate()の問題の記録を使います。モデルクラスは次の通りです。私はclass Metaにordeng='-date_を設置しました。create''とは、モデルオブジェクトが返した記録結果セットをこのフィールドで並べ替えます。
class SystemUserPushHistory(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
host_name = models.CharField(max_length=128, null=False)
system_username = models.CharField(max_length=128, null=False)
method = models.CharField(max_length=32, null=False)
is_success = models.BooleanField(default=False)
date_create = models.DateTimeField(auto_now_add=True, editable=False)
message = models.CharField(max_length=4096, null=True)
class Meta:
db_table = "assets_systemuser_push_history"
ordering = ['-date_create']
def __str__(self):
ret = self.system_username + " => " + self.host_name
return ret
業務に需要があるときは、例えばhost_nameはグループ表示を行い、コードにannotateを使用しました。以下の通りです。
>>> from django.db.models import Count
>>> from assets.models import SystemUserPushHistory
>>> p = SystemUserPushHistory.objects.values("host_name").annotate(dcount=Count(1))
>>> p
<QuerySet [{'host_name': ' 2', 'dcount': 1}, {'host_name': ' 3', 'dcount': 2}, {'host_name': ' 2', 'dcount': 1}, {'host_name': ' 3', 'dcount': 1}]>
>>> print(p.query)
SELECT `assets_systemuser_push_history`.`host_name`, COUNT(1) AS `dcount` FROM `assets_systemuser_push_history` GROUP BY `assets_systemuser_push_history`.`host_name`, `assets_systemuser_push_history`.`date_create` ORDER BY `assets_systemuser_push_history`.`date_create` DESC
得られた結果は私達が予想したようには見えません。その後実行したsqlを出力してグループトップbyにいる時はホストに対して見られます。nameとdate_createでグループ化するのは、modelクラスにordeingを設置しています。削除したらコードが正常に運行されます。distinctを使うのは上の状況と似ていますので、載せません。
以上のこのDjango多層ネストされたManyToManyフィールドORMの操作の詳細は、小編集が皆さんに提供している内容の全てです。参考にしていただければ幸いです。どうぞよろしくお願いします。