一、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))