【问题标题】:How to specify lookup_field in django如何在 django 中指定lookup_field
【发布时间】:2020-11-18 15:47:45
【问题描述】:

我将在 django 中使用 UpdateAPIView。当我完成视图并运行服务器时,出现以下错误。

Expected view updateViewSet to be called with a URL keyword argument named "pk". Fix your URL conf, or set the `.lookup_field` attribute on the view correctly.

我想知道为什么我不应该在我的代码中将 lookup_field 指定为 pk,以及我可以使用什么来代替 pk。这是我的代码

序列化器.py

from rest_framework import serializers
from .models import arduino

class arduinoSerializers (serializers.ModelSerializer) :
    name = serializers.CharField(source='name.username', read_only=True)
    class Meta :
        model = arduino
        fields = ['name', 'temp', 'humi']

views.py

from .models import arduino
from .serializers import arduinoSerializers
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework.generics import CreateAPIView, UpdateAPIView

class arduinoViewSet (ViewSet) :
    serializer_class = arduinoSerializers
    
    def data (self, request) :
        queryset = arduino.objects.filter(name=self.request.user)
        serializer = arduinoSerializers(queryset, many=True)
        return Response(serializer.data)
        
class createViewSet (CreateAPIView) :
    serializer_class = arduinoSerializers

    def perform_create (self, serializer) :
        serializer.save(name=self.request.user)

    def get_queryset (self) :
        user = self.request.user
        return arduino.objects.filter(name=user)

    def dataReceive (self, request) :
        queryset = self.get_queryset()
        serializer = arduinoSerializers(queryset, many=True)
        if serializer.is_valid() :
            perform_create(serializer)
        return Response(serializer.data)

class updateViewSet (UpdateAPIView) :
    serializer_class = arduinoSerializers
    lookup_field = 'pk'

    def perform_update (self, serializer) :
        serializer.update(name=self.request.user)

    def get_queryset (self) :
        user = self.request.user
        return arduino.objects.filter(name=user)

    def dataReceive (self, request) :
        queryset = self.get_queryset()
        serializer = arduinoSerializers(queryset, many=True)
        if serializer.is_valid() :
            perform_update(serializer)
            return Response(serializer.data)

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('api.urls')),
    path('auth/', include('rest_auth.urls')),
    path('auth/registration/', include('rest_auth.registration.urls')),
]

api\urls.py

urlpatterns = [
    path('data/', arduinoViewSet.as_view({'get' : 'data'})),
    path('create/', createViewSet.as_view()),
    path('update/', updateViewSet.as_view()),
]

提前致谢

【问题讨论】:

  • 可以分享一下网址吗?
  • 我重新上传了!!

标签: django django-rest-framework django-views django-generic-views


【解决方案1】:
更新视图不​​知道要更新哪个 id(pk)。尝试在更新 url 中添加 pk
urlpatterns = [
    path('update/<int:pk>/', updateViewSet.as_view()),
]

【讨论】:

    【解决方案2】:

    据说需要用主键调用url,所以应该是

    urlpatterns = [
        path('data/<int:pk>/', arduinoViewSet.as_view({'get' : 'data'})),
    ]
    

    但老实说,我认为 pk 可以是任何值,只要它是唯一的,但你的错误首先发生是因为,由于你没有指定一个字段,Django 会寻找一个名为 'pk' 的值。

    【讨论】:

    • 谢谢,但还不行:( 浏览器重复同样的错误
    【解决方案3】:

    虽然接受的答案解决了您遇到的问题,但由于您的问题的标题更普遍地与指定 UpdateView 的查找字段有关,我想继续发布这个更一般的答案如果他们尝试基于pk 以外的其他内容进行查找,则可能会遇到此问题的任何人。

    查看CCBV docs for UpdateView.get_object(),您可以看到如果&lt;int:pk&gt; 不在url 中,那么UpdateView 会查找slug_field(默认名称为slug,您可以在上面的属性下看到页)。因此,您可以将 &lt;slug:slug&gt; 放在 url 中,而不是 &lt;int:pk&gt;。在这种情况下,声明的&lt;slug:slug&gt; 部分中的第二个slugUpdateView 使用的默认url 关键字,如果通过蛞蝓查找。顺便说一句,如果您在 url 声明中将 slug 关键字参数命名为:&lt;slug:different_slug_name&gt;,那么您需要在 UpdateView 上指定 slug_url_kwarg = different_slug_name。最后,如果SlugField 在您的模型上 被命名为 slug 以外的名称(同样,您可以在 CCBV 的属性中看到默认值),那么在 UpdateView 上您需要指定slug_field = model_slug_field_name

    【讨论】:

      猜你喜欢
      • 2021-05-23
      • 2021-03-05
      • 2017-10-29
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多