【问题标题】:Django REST framework: nested relationship: non_field_errorsDjango REST 框架:嵌套关系:non_field_errors
【发布时间】:2014-09-18 20:11:33
【问题描述】:

在一个 Django-REST-framework 项目中,我尝试使用嵌套关系并在可浏览的 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 界面表单也能正常工作,那就更好了。特别是因为我想知道是否发生了一些有趣的事情。

提前谢谢你!

【问题讨论】:

    标签: python django rest django-rest-framework


    【解决方案1】:

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

    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 错误。

    【讨论】:

    • 太棒了,您的解决方案对我有用,虽然我不明白为什么将ForeignKey 字段'tracks' 像read_only_fields 属性/属性和depth 一样。 depth 和 read_only_fields 是关键字属性吗?
    • 并且api rest框架中序列化的字段(本例中为tracks)是只读的。如何使字段可以通过 put 更新或可以创建一个新实例? (album 在这种情况下...)
    【解决方案2】:

    一种解决方案是简单地在浏览器端隐藏 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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-28
      • 2015-04-05
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      • 2014-05-21
      • 2015-04-16
      相关资源
      最近更新 更多