django 外键的其他字段等处理方式


  

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

 

 





免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM