一、admin 顯示外鍵的其他字段
#models
class Category(models.Model): name = models.CharField(max_length=64,unique=True) admins = models.ForeignKey(User,blank=True,on_delete=models.CASCADE) class Meta: verbose_name = '分類' verbose_name_plural = '分類'
class Comment(models.Model):
article = models.ForeignKey(Article,verbose_name=u"所屬文章",on_delete=models.CASCADE)
user = models.ForeignKey(User,on_delete=models.CASCADE)
comment = models.TextField(blank=True,null=True)# 問題來了? 點贊不用內容,但是評論要內容啊!!!
date = models.DateTimeField(auto_now_add=True)
def clean(self):
if len(self.comment) ==0:
raise ValidationError(u'評論內容不能為空')
def __str__(self):
return self.comment
class Meta:
verbose_name = '評論'
verbose_name_plural = '評論'
# admin.py
class CommentAdmin(admin.ModelAdmin):
list_display = ('article','comment','user','date') user 如果是外鍵的話顯示user的ID
class CategoryAdmin(admin.ModelAdmin): list_display = ('name','admins') 這里admin 顯示外鍵的username字段 def admins(self,obj): return obj.admins.username
二、序列化顯示外鍵其他字段
我們使用source
class CommentSerializer(serializers.ModelSerializer): # username = serializers.CharField(source='user.username') 顯示user外鍵的username class Meta: model = Comment fields = ('username')
二、直接在model中通過property裝飾器創建一個名為questionnaire_title的函數,並在函數中返回我們想要拿到的信息如:questionnaire_name,questionnaire_id,然后在序列化時指定為ReadOnlyField()字段;具體操作如下
models.py
class Questionnaire(models.Model):
'''問卷'''
title = models.CharField('標題',max_length=100)
class Meta:
verbose_name_plural = '所有問卷'
class Question(models.Model):
'''問題'''
#所屬問卷
questionnaire = models.ForeignKey(Questionnaire,verbose_name='所屬問卷',related_name='questions')
#問題標題
title = models.CharField('問題',max_length=150)
#是否是多選
is_checkbox = models.BooleanField('是否多選',default=False,help_text='是否是多選問題')
class Meta:
verbose_name_plural = '問題'
@property
def questionnaire_title(self):
return self.questionnaire.title,self.questionnaire.id
serializers.py使用ReadOnly
from rest_framework import serializers
from question.models import Question,Questionnaire
class QuestionnaireSerializer(serializers.ModelSerializer):
class Meta:
model = Questionnaire
fields = ('title',)
class QuestionSerializer(serializers.ModelSerializer):
questionnaire_title = serializers.ReadOnlyField()
questionnaire_id = serializers.ReadOnlyField()
class Meta:
model = Question
如果只讀的話 后端方法: 方法一 class BrandModelNumberSerializer(serializers.ModelSerializer): brand = serializers.SerializerMethodField() class Meta: model = BrandModelNumber fields = "__all__" def get_brand(self, obj): return obj.brand.name 總之就是使用SerializerMethodField,並寫出get_brand,讓其返回你要顯示的對象就行了 p.s.SerializerMethodField在model字段顯示中很有用。 方法二: class BrandModelNumberSerializer(serializers.ModelSerializer): brand_name = serializers.ReadOnlyField(source='brand.name') # brand = serializers.SlugRelatedField(read_only=True ,slug_field='name') ① # brand = serializers.StringRelatedField(label='類別') ② class Meta: model = BrandModelNumber fields = "__all__"
三。models
class Article(models.Model): title = models.CharField(max_length=255,verbose_name='文章標題',help_text='文章標題') # 所屬版塊 Category類位於Article下面時,調用需要加上引號 category = models.ForeignKey("Category",verbose_name='分類',help_text='分類',on_delete=models.CASCADE) 未定義的外鍵表 用"Category" django新版本外鍵要加on_delete content = models.TextField(u"文章內容") author = models.ForeignKey("UserProfile",on_delete=models.CASCADE) # auto_now 和 auto_now_add 區別? # 每次對象修改了,保存都會更新auto_now的最新時間 # 每次對象創建的時候,會生成auto_now_add 時間 pub_date = models.DateTimeField(blank=True, null=True) last_modify = models.DateTimeField(auto_now=True) # 文章置頂功能 priority = models.IntegerField(u"優先級",default=1000) head_img = models.ImageField(u"文章標題圖片",upload_to="uploads",default="uploads/default.jpg") status_choices = (('draft',u"草稿"), ('published',u"已發布"), ('hidden',u"隱藏"), ) status = models.CharField(choices=status_choices,default='published',max_length=32) def __str__(self): return self.title
def clean(self): # 自定義model驗證(除django提供的外required max_length 。。。),驗證model字段的值是否合法
# Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None:
raise ValidationError(('Draft entries may not have a publication date.'))
# Set the pub_date for published items if it hasn't been set already.
if self.status == 'published' and self.pub_date is None:
self.pub_date = datetime.date.today()
class Meta:
verbose_name = '文章'
verbose_name_plural = '文章'
parent_category = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, verbose_name="父類目級別", help_text="父目錄",related_name="sub_cat")
指向自己 self ,外鍵是自己的方式。怎么做序列化
class GoodsCategory(models.Model): """ 商品分類 """ CATEGORY_TYPE = ( (1, "一級類目"), (2, "二級類目"), (3, "三級類目"), ) name = models.CharField('類別名',default="", max_length=30,help_text="類別名") code = models.CharField("類別code",default="", max_length=30,help_text="類別code") desc = models.TextField("類別描述",default="",help_text="類別描述") #目錄樹級別 category_type = models.IntegerField("類目級別",choices=CATEGORY_TYPE,help_text="類目級別") # 設置models有一個指向自己的外鍵 parent_category = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, verbose_name="父類目級別", help_text="父目錄",related_name="sub_cat")
關聯到同一張表的時候需要關聯自己用self,當關聯自己以后 想反向查找需要通過related_name來查,
class Meta: verbose_name = "商品類別" verbose_name_plural = verbose_name def __str__(self): return self.name
serializer
class CategorySerializer3(serializers.ModelSerializer):
'''三級分類'''
class Meta:
model = GoodsCategory
fields = ['name','code','desc','category_type','parent_category']
#
class CategorySerializer2(serializers.ModelSerializer):
'''二級分類'''
sub_cat = CategorySerializer3(many=True) #sub_cat為外鍵的related_name
class Meta:
model = GoodsCategory
fields = ['name','code','desc','category_type','parent_category','sub_cat']
class CategorySerializer(serializers.ModelSerializer):
'''商品一級分類'''
sub_cat= CategorySerializer2(many=True)
class Meta:
model = GoodsCategory
fields = ['name','code','desc','category_type','parent_category','sub_cat']
views
class GoodViewSet(viewsets.ModelViewSet):
"""
域名列表,分頁,搜索,過濾,排序
"""
queryset = GoodsCategory.objects.filter(category_type=1)
serializer_class = CategorySerializer
--------------------------------------------------------------------------------------------------------------------------
class eventinfo(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=100, verbose_name='主題') source = models.ForeignKey(datacate,on_delete=models.SET_NULL, verbose_name="事件來源",null=True, blank=True) Request = models.CharField(max_length=100, verbose_name='報障者') info = models.TextField(verbose_name='描述', blank=True, null=True) start_time = models.DateTimeField(auto_now=True,verbose_name='添加時間') status = models.BooleanField(default=False, verbose_name="事件狀態",help_text='事件狀態') end_time = models.DateTimeField(verbose_name='關閉時間',blank=True, null=True) #event_type = models.ForeignKey(Type,on_delete=models.SET_NULL, verbose_name="事件類型",null=True, blank=True) #event_app = models.ForeignKey(App,on_delete=models.SET_NULL, verbose_name="所屬應用",null=True, blank=True) #event_product = models.ForeignKey(product,on_delete=models.SET_NULL, verbose_name="所屬產品",null=True, blank=True) #event_rank = models.ForeignKey(Rank,on_delete=models.SET_NULL, verbose_name="事件等級",null=True, blank=True) class Meta: verbose_name = '事件信息' verbose_name_plural = '事件信息' def __str__(self): return self.title class Solution(models.Model): id = models.AutoField(primary_key=True) event = models.ForeignKey(eventinfo,verbose_name="所屬事件",on_delete=models.CASCADE,related_name="solution_info") solver = models.CharField(max_length=100, verbose_name='處理者') rootcause = models.TextField(verbose_name='根源',null=True, blank=True) solution = models.TextField(verbose_name='處理方法') sol_time = models.DateTimeField(auto_now=True,verbose_name='處理時間') class Meta: verbose_name = '處理工單' verbose_name_plural = '處理工單'
class SolutionSerializer(serializers.ModelSerializer):
class Meta:
model = Solution
fields = ('__all__')
class InfoSerializer(serializers.ModelSerializer):
type_name = serializers.ReadOnlyField(source='event_type.name')
app_name = serializers.ReadOnlyField(source='event_app.app_name')
product_name = serializers.ReadOnlyField(source='event_product.name')
rank_name = serializers.ReadOnlyField(source='event_rank.name')
source_name = serializers.ReadOnlyField(source='source.name')
solution_info = SolutionSerializer(many=True) #get也獲取到solution的列表
solution_num = serializers.SerializerMethodField() #獲取到solution的數目
class Meta:
model = eventinfo
fields = ('__all__')
def get_solution_num(self, obj):
return len(Solution.objects.filter(event = obj.id))