您好,登錄后才能下訂單哦!
Django中想要把模型類聚合得到想要的數據可以用F對象。
比如有模型類A和B,A和B之間有外鍵關聯在一起,A是子表,B是父表(反過來沒試過。。因為大部分數據都是用子表的,我想是可以的),那么可以這樣查:
A.objects.filter(userid=3,bookid=F(bid))
其中userid,bookid是模型類A的字段,bid是模型類B的字段。
這樣操作的結果就是可以查詢到userid為3且模型類A字段bookid等于模型類B字段bid的集合數據了。
F對象是可以比較兩個關聯模型類的字段數據的。
我看到網上有說F對象可以這樣用F('b__id') ==>F('模型類名小寫__字段名'),此處是雙下劃線。
但是我用Django2.0時會報錯。。真是搞不懂,后來我直接使用字段名居然可以,醉了。
反正都可以試試吧
A.objects.filter(userid=3,bookid=F(bid))
A.objects.filter(userid=3,bookid=F('b__bid'))
補充知識:Django Admin頁面顯示父表,編輯子表
默認情況下,ModelAdmin只允許您管理模型“本身”字段,而不是相關模型.以下方法將實現,在應用類的列表管理顯示頁面,顯示父表的字段;在編輯頁面,父表對子表進行編輯.
models.py如下
class Level(models.Model): # l_num = models.IntegerField(default=0, verbose_name='序號') name = models.CharField(max_length=20) is_delete = models.BooleanField(default=False) def __str__(self): return self.name class Grades(models.Model): name = models.CharField(max_length=20, verbose_name='班級') # 外鍵,這里關聯模型Level與模型名稱一樣,不是全小寫。 level = models.ForeignKey('Level', on_delete=models.DO_NOTHING) is_delete = models.BooleanField(default=False) def __str__(self): return '%s%s' % (self.level, self.name) class Students(models.Model): name = models.CharField(max_length=20, db_index=True, verbose_name='姓名') age = models.IntegerField(verbose_name='年齡') # 需要先提供一個二維的二元元組,第一個元素表示存在數據庫內真實的值,第二個表示頁面上顯示的具體內容 SEX_CHOICE = ( ('男', '男'), ('女', '女'), ) sex = models.CharField(max_length=10, choices=SEX_CHOICE, verbose_name='性別', default='男') grade = models.ForeignKey('Grades', on_delete=models.DO_NOTHING, verbose_name="班級") img_student = models.ImageField(upload_to='img_student', default='img_student/default.png', verbose_name='頭像') create_time = models.DateTimeField(auto_now_add=True, verbose_name='創建時間') last_update_time = models.DateTimeField(auto_now=True, verbose_name='上次更新時間') is_delete = models.BooleanField(default=False) def __str__(self): return self.name
在admin.py代碼如下:
@admin.register(Students) class StudentsAdmin(admin.ModelAdmin): list_display = ('name', 'age', 'sex', 'grade', 'create_time', 'last_update_time', 'is_delete')
做完之后,顯示的效果如下:
在應用類的列表管理顯示頁面,顯示父表的字段
可以讓Students,顯示父表Grades的父表Level字段
在models.py里的Students類里,寫上如下代碼:
class Students(models.Model):
# 寫一個方法,定義在管理頁面上能夠顯示的外鍵字段字段 # grade為Students模型的外檢表,level為Grades模型的外檢表,那么為Level模型的字段 def dis_level(self): return self.grade.level.name # 定義該字段在管理后臺顯示的名稱 dis_level.short_description = '年級' # 定義該字段在管理后臺顯示的名稱 dis_level.short_description = '年級' # 方法列是不能排序的,如果需要排序需要為方法指定排序依據。添加的是'模型類字段' # 如果是外鍵需要遵循這樣的語法:本表外鍵字段__(雙下劃線)外檢表字段或外檢表的外鍵字段__最終外鍵表要顯示的字段。 dis_level.admin_order_field = 'grade__level__name'
在admin.py里,把Students類里的方法,加入到list_display里:
@admin.register(Students) class StudentsAdmin(admin.ModelAdmin): list_display = ('name', 'age', 'sex', 'grade', 'dis_level', 'create_time', 'last_update_time', 'is_delete')
寫完之后,顯示的結果如下,多了年級,以及點擊年級可以進行排序:
在編輯頁面,父表對子表進行編輯.
默認對學生編輯時,無法在編輯頁面直接編輯相關聯的子表,例如:
models.py代碼:
class Students(models.Model): name = models.CharField(max_length=20, db_index=True, verbose_name='姓名') age = models.IntegerField(verbose_name='年齡') # 需要先提供一個二維的二元元組,第一個元素表示存在數據庫內真實的值,第二個表示頁面上顯示的具體內容 SEX_CHOICE = ( ('男', '男'), ('女', '女'), ) sex = models.CharField(max_length=10, choices=SEX_CHOICE, verbose_name='性別', default='男') grade = models.ForeignKey('Grades', on_delete=models.DO_NOTHING, verbose_name="班級") img_student = models.ImageField(upload_to='img_student', default='img_student/default.png', verbose_name='頭像') create_time = models.DateTimeField(auto_now_add=True, verbose_name='創建時間') last_update_time = models.DateTimeField(auto_now=True, verbose_name='上次更新時間') is_delete = models.BooleanField(default=False) def __str__(self): return self.name class Course(models.Model): name = models.CharField(max_length=20, verbose_name='課名') is_delete = models.BooleanField(default=False) def __str__(self): return self.name class Score(models.Model): s_score = models.IntegerField(default=0, verbose_name='分數') s_course = models.ForeignKey('Course', on_delete=models.DO_NOTHING, verbose_name='課程') s_student = models.ForeignKey('Students', on_delete=models.DO_NOTHING, verbose_name='學生姓名') is_delete = models.BooleanField(default=False) def __str__(self): # 要把s_score轉換為字符串,否則會報下面的錯誤。 """ Exception Type:TypeError Exception Value: __str__ returned non-string (type int) :return: """ return '%s%s%s' % (self.s_student, self.s_course, str(self.s_score))
打開學生的編輯頁面,是這樣子的:
要給學生添加分數,只能進入Score管理頁面,一個個添加,非常麻煩.
使用Django的TabularInline,可以解決這個問題,在父表里對子表進行編輯:
所有代碼都在admin.py里寫,具體如下:
# 一對多關聯表編輯,讓父表管理配置頁面能同時編輯子表,以下的Score為子表(有外鍵所在的表) class ScoreInline(admin.TabularInline): # Score 必須是models.py中的模型名稱,大小寫必須要匹配.這個模型為子表,以便可以被父表編輯 model = Score # 默認顯示條目的數量 # extra = 5 class StudentsAdmin(admin.ModelAdmin): # Inline把ScoreInline關聯進來,讓父表管理配置頁面能同時編輯子表. inlines = [ScoreInline, ]
做完之后,效果如下:
以上這篇使用Django實現把兩個模型類的數據聚合在一起就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。