如何在 Django 中指定 lookup_field
How to specify lookup_field in django
我打算在 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。这是我的代码
serializers.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()),
]
提前致谢
据说需要用主键调用URL,所以应该是
urlpatterns = [
path('data/<int:pk>/', arduinoViewSet.as_view({'get' : 'data'})),
]
但老实说,我认为 pk 可以是任何值,只要它是唯一的,但是你的错误首先发生是因为,因为你没有指定字段,Django 会寻找一个名为 'pk'.
更新视图不知道要更新哪个 id(pk)。尝试在更新中添加 pk url
urlpatterns = [
path('update/<int:pk>/', updateViewSet.as_view()),
]
虽然接受的答案解决了您遇到的问题,但由于您的问题的标题更普遍地与指定 UpdateView
的查找字段有关,我想继续 post 对于可能遇到此问题的任何人,如果他们试图根据 pk
.
以外的其他内容进行查找,这是一个更通用的答案
查看 CCBV docs for UpdateView.get_object(), you can see that if <int:pk>
is not in the url, then UpdateView
looks for slug_field
(with a default name of slug
which you can see under Attributes on the above page). Therefore, instead of <int:pk>
in the url, you could put <slug:slug>
in the url. In this case the second slug
in the <slug:slug>
part of the declaration is the default url keyword used by UpdateView
if looking up by a slug. As an aside, if you name your slug keyword argument in your url declaration something like: <slug:different_slug_name>
, then you would need to specify slug_url_kwarg = different_slug_name
on the UpdateView
. Finally, if the SlugField 在您的模型上 被命名为 slug
以外的名称(同样,您可以在 CCBV 的属性中看到默认值) , 然后在 UpdateView
上你需要指定 slug_field = model_slug_field_name
.
我打算在 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。这是我的代码
serializers.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()),
]
提前致谢
据说需要用主键调用URL,所以应该是
urlpatterns = [
path('data/<int:pk>/', arduinoViewSet.as_view({'get' : 'data'})),
]
但老实说,我认为 pk 可以是任何值,只要它是唯一的,但是你的错误首先发生是因为,因为你没有指定字段,Django 会寻找一个名为 'pk'.
urlpatterns = [
path('update/<int:pk>/', updateViewSet.as_view()),
]
虽然接受的答案解决了您遇到的问题,但由于您的问题的标题更普遍地与指定 UpdateView
的查找字段有关,我想继续 post 对于可能遇到此问题的任何人,如果他们试图根据 pk
.
查看 CCBV docs for UpdateView.get_object(), you can see that if <int:pk>
is not in the url, then UpdateView
looks for slug_field
(with a default name of slug
which you can see under Attributes on the above page). Therefore, instead of <int:pk>
in the url, you could put <slug:slug>
in the url. In this case the second slug
in the <slug:slug>
part of the declaration is the default url keyword used by UpdateView
if looking up by a slug. As an aside, if you name your slug keyword argument in your url declaration something like: <slug:different_slug_name>
, then you would need to specify slug_url_kwarg = different_slug_name
on the UpdateView
. Finally, if the SlugField 在您的模型上 被命名为 slug
以外的名称(同样,您可以在 CCBV 的属性中看到默认值) , 然后在 UpdateView
上你需要指定 slug_field = model_slug_field_name
.