1. 在drf序列化model时,默认只显示id而不是内容,但前端是需要外键的值。
class User(BaseModel, AbstractUser): is_system = models.BooleanField(null=False, blank=False, default=False, verbose_name='是否为教务人员') gender_choice = (('male', '男'), ('female', '女')) ROLE = ((0, '教务人员'), (1, '老师')) roles = models.IntegerField(blank=True, choices=ROLE, default=0, verbose_name='角色') gender = models.CharField(null=False, blank=False, choices=gender_choice, default='male', max_length=6,verbose_name='性别') subjects = models.CharField(blank=False, null=False, max_length=12, verbose_name="任教科目") u_class = models.CharField(max_length=32, verbose_name="任教班级") class Meta: verbose_name = '用户' verbose_name_plural = verbose_name db_table = 'basic_user' ordering = ('username',) def __str__(self): return self.usernameclass ClassManagement(BaseModel): CLASS_CHOICE = ((0, '文科'), (1, '理科')) class_type = models.IntegerField(null=False, blank=False, choices=CLASS_CHOICE, verbose_name="班级类型") class_name = models.CharField(null=True, blank=True, max_length=32, unique=False, verbose_name='班级名称') class_number = models.IntegerField(verbose_name="班级人数") class_teacher = models.ForeignKey(to=User, related_name="+", on_delete=models.SET_NULL, null=True, blank=True,verbose_name="班主任") class_level = models.IntegerField(verbose_name="年级", default=1) class Meta: verbose_name = '班级表' verbose_name_plural = verbose_name unique_together = ['class_name'] db_table = 'class_management' ordering = ('class_name',) def __str__(self): return self.class_name
方法一、在序列化的时候,就创建一个新字段class_teacher_name,指定为serializers.CharField而且字段使用 source 这个属性,具体而言格式为:
CharField(source='<本model中的外键>.<外键指向的model的相应属性>')
class ClassManagementSerializer(serializers.ModelSerializer): class_teacher_name = serializers.CharField(source='class_teacher.username') class Meta: model = ClassManagement fields = "__all__"
方法二、在model中增加 @property 装饰器
class ClassManagement(BaseModel): CLASS_CHOICE = ((0, '文科'), (1, '理科')) class_type = models.IntegerField(null=False, blank=False, choices=CLASS_CHOICE, verbose_name="班级类型") class_name = models.CharField(null=True, blank=True, max_length=32, unique=False, verbose_name='班级名称') class_number = models.IntegerField(verbose_name="班级人数") class_teacher = models.ForeignKey(to=User, related_name="+", on_delete=models.SET_NULL, null=True, blank=True, verbose_name="班主任") class_level = models.IntegerField(verbose_name="年级", default=1) class Meta: verbose_name = '班级表' verbose_name_plural = verbose_name unique_together = ['class_name'] db_table = 'class_management' ordering = ('class_name',) def __str__(self): return self.class_name @property def class_teacher_name(self): return self.class_teacher.username # 使用 ReadOnlyField()class ClassManagementSerializer(serializers.ModelSerializer): class_teacher_name = serializers.ReadOnlyField() class Meta: model = ClassManagement fields = "__all__"
方法三、在serializers里使用SerializerMethodField()
class ClassManagementSerializer(serializers.ModelSerializer): class_teacher_name = serializers.SerializerMethodField() class Meta: model = ClassManagement fields = "__all__" def get_class_teacher_name(self, obj): # obj.本model中的外键.外键指向的model的相应属性 return obj.class_teacher.username
2. model中使用choices,但是序列化的时候想要显示选项的value,但是在反序列化的时候想要接收key。
class ClassManagement(BaseModel): CLASS_CHOICE = ((0, '文科'), (1, '理科')) class_type = models.IntegerField(null=False, blank=False, choices=CLASS_CHOICE, verbose_name="班级类型") class_name = models.CharField(null=True, blank=True, max_length=32, unique=False, verbose_name='班级名称') class_number = models.IntegerField(verbose_name="班级人数") class_teacher = models.ForeignKey(to=User, related_name="+", on_delete=models.SET_NULL, null=True, blank=True, verbose_name="班主任") class_level = models.IntegerField(verbose_name="年级", default=1) class Meta: verbose_name = '班级表' verbose_name_plural = verbose_name unique_together = ['class_name'] db_table = 'class_management' ordering = ('class_name',) def __str__(self): return self.class_nameclass ClassManagementSerializer(serializers.ModelSerializer): class_teacher_name = serializers.SerializerMethodField() class Meta: model = ClassManagement fields = "__all__" def get_class_teacher_name(self, obj): return obj.class_teacher.username # 重写drf的 to_representation 方法 def to_representation(self, instance): data = super().to_representation(instance) # data.update 语法为:model中使用choices的字段 = instance.get_model中字段名_display() data.update(class_type=instance.get_class_type_display()) return data
3. django ForeignKey(外键) 设置允许为空。
class Writer(models.Model): name=models.CharField(max_length=60,verbose_name="名字")class Books(models.Model): # null 主要是用于写入数据库使用,null默认为False,也就是说django默认是所有字段都需要有值才可以正常写入数据库。 writer=models.ForeignKey('Writer',blank = True,null=True)