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