【发布时间】:2020-02-05 07:51:54
【问题描述】:
所以我想用序列化器创建一个反馈对象:
class Location(models.Model):
name = models.CharField(max_length=256)
img_small = models.CharField(max_length=1024, blank=True, null=True)
img_large = models.CharField(max_length=1024, blank=True, null=True)
class Meta:
managed = True
db_table = 'location'
class Schedules(models.Model):
user = models.ForeignKey(Users, models.DO_NOTHING, default=None)
name = models.CharField(max_length=512, blank=True, null=True)
location = models.ForeignKey(Location, models.DO_NOTHING, default=None)
detail = models.TextField(blank=True, null=True)
start = models.DateField()
end = models.DateField()
created = models.DateTimeField(blank=True, null=True)
modified = models.DateTimeField(blank=True, null=True)
class Meta:
managed = True
db_table = 'schedules'
class Feedbacks(models.Model):
location = models.ForeignKey(Location, models.DO_NOTHING)
schedule = models.ForeignKey(Schedules, models.DO_NOTHING)
start = models.IntegerField(blank=True, null=True)
end = models.IntegerField(blank=True, null=True)
created = models.DateTimeField(blank=True, null=True)
modified = models.DateTimeField(blank=True, null=True)
class Meta:
managed = True
db_table = 'feedbacks'
和序列化程序类:
class FeedbackSerializer(serializers.ModelSerializer):
location_id = serializers.PrimaryKeyRelatedField(queryset=Location.objects.all())
schedule_id = serializers.PrimaryKeyRelatedField(queryset=Schedules.objects.all())
class Meta:
model = Feedbacks
fields = ('location_id', 'schedule_id', 'start', 'end')
# read_only_fields = ('location_id', 'schedule_id')
我的数据是
{"location_id" : 2, "schedule_id" : 2, "start" : "1", "end" : 2}
问题是验证后我的验证数据包含 Location 和 Schedule 对象,而不是 id,所以我无法插入并收到此错误
int() argument must be a string, a bytes-like object or a number, not 'Location'
【问题讨论】:
-
这行得通吗? -
location_id = serializers.PrimaryKeyRelatedField(queryset=Location.objects.all(), source='location') -
是的,它有效。非常感谢。但是你能解释一下这是如何工作的吗?据我了解,“源”关键字告诉我该字段属于模型的哪个属性。但是如果我不需要用 start 和 end 来做,为什么 location_id 和 schedule_id 不一样?
-
要了解实际问题,您需要了解 django 模型在定义 ForeignKey 字段时是如何工作的。例如,如果您将
location定义为 FK,那么在幕后您还会得到一个location_id,它是它的实际 id(不是实例,它位于location字段上)。您可以尝试在Feedback对象上打印这些字段并查看差异。如果您输入location_id,则返回序列化程序,它期望它的 id 不是Location的实例(您得到它是因为PrimaryKeyRelatedField在验证后返回),因此您会收到错误。 -
@GabrielMuj 我现在有点理解这个概念,但对我来说,它仍然感觉有点奇怪。验证过程知道 location_id 是一个 int,它指的是 location 对象的 id,但仍然返回该对象。
-
@NhatTon 即使您发送了 id,您也会因为来自
PrimaryKeyRelatedField的方法to_internal_value而取回对象。该方法使用queryset,然后在id 上执行get(您可以查看它的源代码)。所以你得到的实际结果是Location的实例。仅出于测试和学习目的,请尝试将IntegerField(如果您的主键是 int)用于location_id,这应该可以工作,因为它将被转换为 int 而不是位置实例。
标签: django django-rest-framework django-serializer