Django REST框架:嵌套关系:non_field_errors

时间:2014-07-27 13:58:30

标签: python django rest django-rest-framework

在Django-REST框架项目中,我尝试使用嵌套关系,并在可浏览的API Web视图中获得“non_field_errors”。

代码来自文档的这一部分: http://www.django-rest-framework.org/api-guide/relations#nested-relationships

models.py:

from django.db import models

class Album(models.Model):
    album_name = models.CharField(max_length=100)
    artist = models.CharField(max_length=100)

class Track(models.Model):
    album = models.ForeignKey(Album, related_name='tracks')
    order = models.IntegerField()
    title = models.CharField(max_length=100)
    #duration = models.IntegerField()

    class Meta:
        unique_together = ('album', 'order')
        ordering = ('order',)

    def __unicode__(self):
        return '%d: %s' % (self.order, self.title)

serializers.py:

from rest_framework import serializers
from myapp.models import Album, Track

class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = ('order', 'title')

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')

错误(在../专辑中):

Track输入字段标记为红色,并显示错误消息:non_field_errors。

单击OPTIONS按钮显示实际和正确的数据结构:

跟踪适当属性的轨道

可浏览浏览器视图的原始数据输入显示:

{
    "album_name": "", 
    "artist": "", 
    "tracks": null
}

发布一些有效的原始数据实际上是有效的。但是,如果Web界面表单也能正常工作,那就更好了。特别是因为我想知道是否还有一些有趣的事情发生了。

提前谢谢!

2 个答案:

答案 0 :(得分:3)

我也遇到过这个问题。摆脱错误的一种方法是使用:

class AlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.RelatedField(many=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')

但是,这会删除嵌套的轨道字段,并仅显示轨道的字符串表示形式。

编辑:我明白了。你想要的是这个:

class AlbumSerializer(serializers.ModelSerializer):

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')
        read_only_fields = ('tracks',)
        depth = 1

这将导致轨道嵌套而不会抛出UI错误。

答案 1 :(得分:0)

一种解决方案是简单地在浏览器端隐藏HTML表单。例如,覆盖Rest Framework的api.html模板(通过创建your_app / templates / rest_framework / api.html)并包含以下内容:

{% extends "rest_framework/base.html" %}

...

{% block script %}
{{ block.super }}
    <script>
    $('.form-switcher a[name="html-tab"]').hide();
    $('.form-switcher a[name="raw-tab"]').tab('show')
</script>
{% endblock %}

如果要保留平面端点的HTML表单并将其从嵌套端点中删除,可以使用name变量作为指示符。例如,在嵌套端点的名称中包含“嵌套”,并执行以下操作:

if("{{ name }}".indexOf("Nested") >= 0){
    $('.form-switcher a[name="html-tab"]').hide();
    $('.form-switcher a[name="raw-tab"]').tab('show').hide();
}