1. 在drf序列化model时,默认只显示id而不是内容,但前端是需要外键的值。

  1. class User(BaseModel, AbstractUser):
  2. is_system = models.BooleanField(null=False, blank=False, default=False, verbose_name='是否为教务人员')
  3. gender_choice = (('male', '男'), ('female', '女'))
  4. ROLE = ((0, '教务人员'), (1, '老师'))
  5. roles = models.IntegerField(blank=True, choices=ROLE, default=0, verbose_name='角色')
  6. gender = models.CharField(null=False, blank=False, choices=gender_choice, default='male', max_length=6,verbose_name='性别')
  7. subjects = models.CharField(blank=False, null=False, max_length=12, verbose_name="任教科目")
  8. u_class = models.CharField(max_length=32, verbose_name="任教班级")
  9. class Meta:
  10. verbose_name = '用户'
  11. verbose_name_plural = verbose_name
  12. db_table = 'basic_user'
  13. ordering = ('username',)
  14. def __str__(self):
  15. return self.username
  16. class ClassManagement(BaseModel):
  17. CLASS_CHOICE = ((0, '文科'), (1, '理科'))
  18. class_type = models.IntegerField(null=False, blank=False, choices=CLASS_CHOICE, verbose_name="班级类型")
  19. class_name = models.CharField(null=True, blank=True, max_length=32, unique=False, verbose_name='班级名称')
  20. class_number = models.IntegerField(verbose_name="班级人数")
  21. class_teacher = models.ForeignKey(to=User, related_name="+", on_delete=models.SET_NULL, null=True, blank=True,verbose_name="班主任")
  22. class_level = models.IntegerField(verbose_name="年级", default=1)
  23. class Meta:
  24. verbose_name = '班级表'
  25. verbose_name_plural = verbose_name
  26. unique_together = ['class_name']
  27. db_table = 'class_management'
  28. ordering = ('class_name',)
  29. def __str__(self):
  30. return self.class_name

方法一、在序列化的时候,就创建一个新字段class_teacher_name,指定为serializers.CharField而且字段使用 source 这个属性,具体而言格式为:

  • CharField(source='<本model中的外键>.<外键指向的model的相应属性>')

    1. class ClassManagementSerializer(serializers.ModelSerializer):
    2. class_teacher_name = serializers.CharField(source='class_teacher.username')
    3. class Meta:
    4. model = ClassManagement
    5. fields = "__all__"

方法二、在model中增加 @property 装饰器

  1. class ClassManagement(BaseModel):
  2. CLASS_CHOICE = ((0, '文科'), (1, '理科'))
  3. class_type = models.IntegerField(null=False, blank=False, choices=CLASS_CHOICE, verbose_name="班级类型")
  4. class_name = models.CharField(null=True, blank=True, max_length=32, unique=False, verbose_name='班级名称')
  5. class_number = models.IntegerField(verbose_name="班级人数")
  6. class_teacher = models.ForeignKey(to=User, related_name="+", on_delete=models.SET_NULL, null=True, blank=True,
  7. verbose_name="班主任")
  8. class_level = models.IntegerField(verbose_name="年级", default=1)
  9. class Meta:
  10. verbose_name = '班级表'
  11. verbose_name_plural = verbose_name
  12. unique_together = ['class_name']
  13. db_table = 'class_management'
  14. ordering = ('class_name',)
  15. def __str__(self):
  16. return self.class_name
  17. @property
  18. def class_teacher_name(self):
  19. return self.class_teacher.username
  20. # 使用 ReadOnlyField()
  21. class ClassManagementSerializer(serializers.ModelSerializer):
  22. class_teacher_name = serializers.ReadOnlyField()
  23. class Meta:
  24. model = ClassManagement
  25. fields = "__all__"

方法三、在serializers里使用SerializerMethodField()

  1. class ClassManagementSerializer(serializers.ModelSerializer):
  2. class_teacher_name = serializers.SerializerMethodField()
  3. class Meta:
  4. model = ClassManagement
  5. fields = "__all__"
  6. def get_class_teacher_name(self, obj):
  7. # obj.本model中的外键.外键指向的model的相应属性
  8. return obj.class_teacher.username

2. model中使用choices,但是序列化的时候想要显示选项的value,但是在反序列化的时候想要接收key。

  1. class ClassManagement(BaseModel):
  2. CLASS_CHOICE = ((0, '文科'), (1, '理科'))
  3. class_type = models.IntegerField(null=False, blank=False, choices=CLASS_CHOICE, verbose_name="班级类型")
  4. class_name = models.CharField(null=True, blank=True, max_length=32, unique=False, verbose_name='班级名称')
  5. class_number = models.IntegerField(verbose_name="班级人数")
  6. class_teacher = models.ForeignKey(to=User, related_name="+", on_delete=models.SET_NULL, null=True, blank=True, verbose_name="班主任")
  7. class_level = models.IntegerField(verbose_name="年级", default=1)
  8. class Meta:
  9. verbose_name = '班级表'
  10. verbose_name_plural = verbose_name
  11. unique_together = ['class_name']
  12. db_table = 'class_management'
  13. ordering = ('class_name',)
  14. def __str__(self):
  15. return self.class_name
  16. class ClassManagementSerializer(serializers.ModelSerializer):
  17. class_teacher_name = serializers.SerializerMethodField()
  18. class Meta:
  19. model = ClassManagement
  20. fields = "__all__"
  21. def get_class_teacher_name(self, obj):
  22. return obj.class_teacher.username
  23. # 重写drf的 to_representation 方法
  24. def to_representation(self, instance):
  25. data = super().to_representation(instance)
  26. # data.update 语法为:model中使用choices的字段 = instance.get_model中字段名_display()
  27. data.update(class_type=instance.get_class_type_display())
  28. return data

3. django ForeignKey(外键) 设置允许为空。

  1. class Writer(models.Model):
  2. name=models.CharField(max_length=60,verbose_name="名字")
  3. class Books(models.Model):
  4. # null 主要是用于写入数据库使用,null默认为False,也就是说django默认是所有字段都需要有值才可以正常写入数据库。
  5. writer=models.ForeignKey('Writer',blank = True,null=True)