Django Rest Framework嵌套可写字段mixins drf_writable_nested

时间:2019-03-18 16:07:58

标签: python django django-rest-framework django-views mixins

我目前正在尝试使用drf_writable_nested来执行我的当前数据库模式的更新和创建,而我一直遇到此错误:

默认情况下,.create()方法不支持可写的嵌套字段。 为串行器.create()编写显式的trvl.serializers.StatisticsSerializer方法,或在嵌套的串行器字段上设置read_only=True

主要型号:

class Statistics(models.Model):
    """Instance: {airport_code, carrier_code, month, year, flight, delay_count, delay_time}"""
    airport = models.ForeignKey(Airport, on_delete=models.CASCADE)
    carrier = models.ForeignKey(Carrier, on_delete=models.CASCADE)
    month = models.IntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(12)])
    year = models.IntegerField(validators=[MinValueValidator(
        1900, message='Invalid year: year < 1900.')])
    # statistics linkage
    flight = models.ForeignKey(
        FlightStatistics, on_delete=models.DO_NOTHING)
    delay_count = models.ForeignKey(
        DelayCountStatistics, on_delete=models.DO_NOTHING)
    delay_time = models.ForeignKey(
        DelayTimeStatistics, on_delete=models.DO_NOTHING)

    # Guaranteeing the "primary key" of the tuple
    class Meta:
        unique_together = ('airport', 'carrier', 'month', 'year')

    def __str__(self):
        return '%s_%s_%s_%s' % (self.airport, self.carrier, self.month, self.year)

序列化器:

class StatisticsSerializer(WritableNestedModelSerializer):
    # Using nest serializer for handling get and post
    # Using serializers instead of the model fields
    flight = FlightStatisticsSerializer()
    delaycount = DelayCountStatisticsSerializer()
    delaytime = DelayTimeStatisticsSerializer()

    class Meta:
        model = models.Statistics
        fields = ('airport', 'carrier', 'month', 'year',
                  'flight', 'delaytime', 'delaycount')

查看:

class StatisticsView(viewsets.ModelViewSet, NestedCreateMixin, NestedUpdateMixin):
queryset = models.Statistics.objects.all()
serializer_class = serializers.StatisticsSerializer

def post(self,request,*args, **kwargs):
    return self.create(request, *args, **kwargs)

def put(self, request, *args, **kwargs):
    return self.update(request, *args, **kwargs)

有效负载示例:

{
    "airport": "ATL",
    "carrier": "AA",
    "month": 7,
    "year": 2008,
    "flight": {
        "cancelled": 2,
        "on_time": 30,
        "total": 100l,
        "delayed": 303,
        "diverted": 121
    },
    "delaytime": {
        "late_aircraft": 21,
        "weather": 2121,
        "security": 2121,
        "national_aviation_system": 21212,
        "carrier": 22
    },
    "delaycount": {
        "late_aircraft": 1212,
        "weather": 1212,
        "security": 1221,
        "national_aviation_system": 1221,
        "carrier": 1212
    }
}

此视图的Django HTML表单: HTML Form

2 个答案:

答案 0 :(得分:0)

您是否尝试过在错误消息中实施建议?

class StatisticsSerializer(WritableNestedModelSerializer):
    # Using nest serializer for handling get and post
    # Using serializers instead of the model fields
    flight = FlightStatisticsSerializer(read_only=True)         # <--
    delaycount = DelayCountStatisticsSerializer(read_only=True) # <--
    delaytime = DelayTimeStatisticsSerializer(read_only=True)   # <--

    class Meta:
        model = models.Statistics
        fields = ('airport', 'carrier', 'month', 'year',
                  'flight', 'delaytime', 'delaycount')

答案 1 :(得分:0)

更新

我决定实现自己的嵌套序列化器:

<div class="item-list">
</div>

.item-list::-webkit-scrollbar {
  -webkit-appearance: none;
  -moz-appearance:none;
  width: 10px;
}

.item-list::-webkit-scrollbar-thumb {
  border-radius: 5px;
  height: 80px;
  background-color: rgba(0,0,0,.5);
  -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}