如何在Django REST框架序列化程序中获取超链接外键?

2024-05-26 17:42:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试序列化我的DRF项目中的模型。该模型包含2个外键字段和一些简单的数据类型字段。其中一个外键字段是我的CustomUser模型,该字段在我的API输出中显示为一个超链接,这是预期的。另一个外键字段指向不同的模型(如下所示)。在过去的几个小时里,我一直在重复同样的几个错误,因为我尝试了其他StackOverflow线程中推荐的各种解决方案

有人能告诉我如何将第二个外键作为链接显示在API输出中吗?

当我的代码文件如下所示时,我在尝试访问localhost:8000/trade/create/localhost:8000/trader-accounts/URL时出现此错误:

django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "traderaccount-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

当然,我在谷歌上搜索了好几次这个错误消息及其部分内容,还下了好几个DRF兔子洞尝试各种各样的东西

交易/模型.py

class Trade(models.Model):
    trade_owner = models.ForeignKey(CustomUser, related_name='owners', on_delete=models.RESTRICT)
    trade_account = models.ForeignKey(TraderAccount, related_name='trades', on_delete=models.RESTRICT)

交易员账户/模型.py

class TraderAccount(models.Model):

    account_owner = models.ForeignKey(
        CustomUser, on_delete=models.CASCADE,
    )
    account_name = models.CharField(
        max_length=200, blank=True, verbose_name='Account Name'
    )

api/serializers.py

class TraderAccountSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = TraderAccount
        fields = ['account_owner', 'account_name',]


class TradeSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Trade
        fields = ['trade_owner', 'trade_account', 'magic_number',]

api/views.py

class TraderAccountView(generics.ListCreateAPIView):
    permission_classes = (IsAuthenticated,)
    queryset = TraderAccount.objects.all()
    serializer_class = TraderAccountSerializer


class TradeCreateView(generics.ListCreateAPIView):
    permission_classes = (IsAuthenticated,)
    queryset = Trade.objects.all()
    serializer_class = TradeSerializer

api/url.py


router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('trader-accounts/', views.TraderAccountView.as_view(), name='trader-accounts'),
    path('trade/create/', views.TradeCreateView.as_view(), name='trade-create'),

当我从api.serializers.TradeSerializer.Meta.fields中删除'trader_account'时,我可以成功访问localhost:8000/trade/create/端点和localhost:8000/trader-accounts/端点

api/serializers.py

# Omit TraderAccountSerializer class for brevity in this example


class TradeSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Trade
        fields = ['trade_owner', 'magic_number',]  # Removed 'trader_account'

我已经看了这么久了,现在我找不到错误。非常感谢你的帮助


Tags: namepy模型apilocalhostmodels错误account
3条回答

您是否尝试过以与user相同的方式为account创建路由

您包含的错误消息表示没有具有预期名称的路由

根据位于https://www.django-rest-framework.org/api-guide/serializers/#how-hyperlinked-views-are-determined的文档,要使自动映射工作,您需要一个名为account-detail的视图,该视图接受1个整数路由参数

正如他们所说,超链接序列化程序非常复杂,所以请密切关注文档。如果更改视图名称,可以在序列化程序中重写它

account = serializers.HyperlinkedRelatedField(
    view_name='account-detail', # or whatever name you give it
    ...
)

基于这个api/views.py你有一个TraderAccountView(generics.ListCreateAPIView)。 您应该将其重命名为TraderAccountList(generics.ListCreateAPIView),然后为详细信息添加一个额外的视图TraderAccountDetail(generics.RetrieveUpdateDestroyAPIView)

api/views.py现在是:

class TraderAccountList(generics.ListCreateAPIView):
    permission_classes = (IsAuthenticated,)
    queryset = TraderAccount.objects.all()
    serializer_class = TraderAccountSerializer

class TraderAccountDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (IsAuthenticated,)
    queryset = TraderAccount.objects.all()
    serializer_class = TraderAccountSerializer

您的URL模式现在应该是

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('trader-accounts/', views.TraderAccountList.as_view(), name='trader-accounts'),
    path('trader-accounts/<int:pk>/', views.TraderAccountDetail.as_view()),
]

并删除TradeCreate。因为您现在正在构建一个RESTful API。要创建交易,您需要向列表视图发出POST请求以创建新交易

在列表视图中,您可以获取所有交易的列表,或者发布一篇文章来创建新交易。 在“详细信息”视图中,您可以执行“获取”以获取特定交易,或执行“放置”或“修补”以更新,或执行“删除”以删除交易

非常感谢Gabbeh为我指明了正确的方向

我将TraderAccountView(generics.ListCreateAPIView)重命名为TraderAccountList(viewsets.ModelViewSet),并将此视图添加到api/views.py

class TraderAccountDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (IsAuthenticated,)
    queryset = TraderAccount.objects.all()
    serializer_class = TraderAccountSerializer

api/urls.py文件现在是:

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
router.register(r'trader-accounts', views.TraderAccountList)

一切正常

相关问题 更多 >

    热门问题