您可能未能在 API 中包含相关模型,或者错误地配置了该字段的“lookup_field”属性

Dan*_*sta 5 python django django-rest-framework

我正在尝试设置两个实体之间的查找字段,但无法修复此错误。

我已经尝试过这些解决方案,但没有一个对我有用(我做错了什么?):

Django Rest Framework,查找字段配置不正确

Django Rest Framework - 无法使用视图名称“user-detail”解析超链接关系的 URL

DRF 无法使用 PrimaryKeyRelatedField 上的视图名称解析超链接关系的 URL

这是我的代码模型:

class Category(models.Model):
    title = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(max_length=80, default='')

    def __str__(self):
        return self.title

class Option(models.Model):
    title = models.CharField(max_length=80)
    slug = models.SlugField(max_length=80, unique=True)
    description = models.CharField(max_length=250)
    price = models.DecimalField(max_digits=7,  decimal_places=2)
    category = models.ForeignKey(Category, related_name='options', on_delete=models.CASCADE)
    photo = models.ImageField(upload_to='options', null=True)

    class Meta:
        ordering = ['title']
    
    def __str__(self):
        return self.title
Run Code Online (Sandbox Code Playgroud)

序列化器:

class CategorySerializer(serializers.HyperlinkedModelSerializer):
    options = serializers.HyperlinkedRelatedField(many=True, view_name='option-detail', read_only=True)
    class Meta:
        model = Category
        fields = ('url', 'slug', 'title', 'options')
        lookup_field = 'slug'
        extra_kwargs = {
            'url': {'lookup_field': 'slug'}
        }

class OptionSerializer(serializers.HyperlinkedModelSerializer):
    category = serializers.ReadOnlyField(source='category.title')
    class Meta:
        model = Option
        fields = ('url', 'slug', 'title', 'description', 'price', 'category')
        lookup_field = 'slug'
        extra_kwargs = {
            'url': {'lookup_field': 'slug'},
            'category': {'lookup_field': 'slug'}
        }
Run Code Online (Sandbox Code Playgroud)

浏览次数:

class CategoryViewSet(viewsets.ReadOnlyModelViewSet):
    """
    Returns the Category list or the requested one
    """
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    lookup_field = 'slug'

class OptionViewSet(viewsets.ReadOnlyModelViewSet):
    """
    Returns the Option list or the requested one
    """
    queryset = Option.objects.all()
    serializer_class = OptionSerializer
    lookup_field = 'slug'
Run Code Online (Sandbox Code Playgroud)

网址:

router = DefaultRouter()
router.register(r'options', views.OptionViewSet)
router.register(r'categories', views.CategoryViewSet)

urlpatterns = [
    path('', include(router.urls)),
]
Run Code Online (Sandbox Code Playgroud)

这适用于选项模型。当我点击“[localhost]/options/”url 时,它会正确列出选项,当点击“[localhost]/options/some-option-slug”时,它会返回正确的选项。

但这些都不适用于类别模型。调用“[localhost]/categories/”返回“无法使用视图名称“option-detail”解析超链接关系的 URL。您可能未能在 API 中包含相关模型,或者错误地配置了lookup_field此字段上的属性。 ”。当调用“[localhost]/categories/category-slug/”时会返回 404 Not Found。

我的 django 版本是 4.0.1,我的 Django Rest Framework 版本是 3.13.1

编辑按照@code-apprendice的建议,这是 print('router') 的输出: [<URLPattern '^options/$' [name='option-list']>, <URLPattern '^options.(?P[ a-z0-9]+)/?$' [name='选项列表']>, <URLPattern '^选项/(?P[^/.]+)/$' [name='选项详细信息' ]>, <URLPattern '^选项/(?P[^/.]+).(?P[a-z0-9]+)/?$' [name='选项详细信息']>, <URLPattern ' ^categories/$' [name='category-list']>, <URLPattern '^categories.(?P[a-z0-9]+)/?$' [name='category-list']>, < URLPattern '^类别/(?P[^/.]+)/$' [name='category-detail']>, <URLPattern '^类别/(?P[^/.]+).(?P[ a-z0-9]+)/?$' [name='category-detail']>, <URLPattern '^$' [name='api-root']>, <URLPattern '^.(?P[a -z0-9]+)/?$' [name='api-root']>]

DRF 正确生成了选项列表、选项详细信息、类别列表和类别详细信息视图

Dan*_*sta 7

为 CategorySerializer 中的选项定义 Lookup_field 属性解决了这个问题。

这是 CategorySerializer 类:

class CategorySerializer(serializers.HyperlinkedModelSerializer):
    options = serializers.HyperlinkedRelatedField(
    view_name='option-detail',
    lookup_field = 'slug',
    many=True,
    read_only=True)

    class Meta:
        model = Category
        fields = ('url', 'slug', 'title', 'options')
        lookup_field = 'slug'
        extra_kwargs = {
            'url': {'lookup_field': 'slug'}
        }
Run Code Online (Sandbox Code Playgroud)

问题是 CategorySerializer 设置了一个显式选项 HyperlinkedRelatedField 并且它的 Lookup_field 也需要配置。

请随意编辑此答案以添加更深入的解释。