我是 Django 初学者,想为我的画家朋友写一个网站。 我想编写一个rest-api,以便我可以访问前端中的模型(我尚未实现)。 当我尝试调用我编写的模型的子域时,我收到错误“‘类型’对象不可迭代”。 我想让注册的用户能够留下反馈,所以我写了一个反馈类。我还实现了 FeedbackSerializer 和 FeedbackView。 我试图使用 chatgpt 但这没有帮助。 stackoverflow 也没有出现任何像我遇到的类似错误。
所以我来这里寻求帮助。 也许你们可以帮助我。
这是我到目前为止想到的:
# api/models.py
class Feedback(models.Model):
title = models.CharField(max_length=1000, null=False, blank=False)
feedback = models.TextField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
image = models.FileField(
upload_to="image", default="default/default-user.jpg", null=True, blank=True)
rating = models.IntegerField(
validators=[MinValueValidator(1), MaxValueValidator(5)], null=False, blank=False)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
super(Feedback, self).save(*args, **kwargs)
# api/serializers.py
class FeedbackSerializer(serializers.ModelSerializer):
class Meta:
model = api_models.Feedback
fields = "__all__"
# api/views.py
class FeedbackView(generics.RetrieveAPIView):
permission_classes = [AllowAny]
serializer_class = api_serializer.FeedbackSerializer
def get_object(self):
feedback_id = self.kwargs["feedback_id"]
try:
feedback = api_models.Feedback.objects.get(id=feedback_id)
except api_models.Feedback.DoesNotExist:
raise Http404("Feedback not found.")
return feedback
# api/urls.py
urlpatterns = [
path("feedback/<feedback_id>/", api_views.FeedbackView.as_view()),
]
完整追溯:
/api/v1/feedback/1/ 处的类型错误
“类型”对象不可迭代
请求方式:GET
请求网址:http://127.0.0.1:8000/api/v1/feedback/1/
Django 版本:5.1
异常类型:TypeError
异常值:
“类型”对象不可迭代
异常位置:/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages/rest_framework/views.py,第 272 行,在 get_authenticators 中
期间引发: api.views.FeedbackDetailView
Python 可执行文件:/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/bin/python3
Python版本:3.11.6
Python路径:
['/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend',
'/usr/lib/python311.zip',
'/usr/lib/python3.11',
'/usr/lib/python3.11/lib-dynload',
'/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages']
服务器时间:2024年8月14日星期三12:24:10 +0000
Traceback 切换到复制粘贴视图
/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages/django/core/handlers/exception.py,第 55 行,在内部
响应 = get_response(请求)
^^^^^^^^^^^^^^^^^^^^^^^ …
本地变量
/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages/django/core/handlers/base.py,第 197 行,在 _get_response 中
响应=wrapped_callback(请求,*callback_args,**callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^...
本地变量
/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages/django/views/decorators/csrf.py,第 65 行,在 _view_wrapper 中
返回 view_func(请求, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
本地变量
/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages/django/views/generic/base.py,第 104 行,查看
返回 self.dispatch(请求, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
本地变量
/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages/rest_framework/views.py,第 492 行,在调度中
请求 = self.initialize_request(请求, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
本地变量
/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages/rest_framework/views.py,第394行,在initialize_request中
验证器= self.get_authenticators(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^...
本地变量
/home/jakob-adler/webdev/malergeschaeft_ernst/malergeschaeft_ernst/backend/env/lib/python3.11/site-packages/rest_framework/views.py,第 272 行,在 get_authenticators 中
返回 [auth() 用于 self.authentication_classes 中的身份验证]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我希望我可以调用子域 /feedback/1/,它会向我显示每个反馈的 API 视图。 我通过管理页面创建了反馈,但不知何故它没有按预期工作
使用DRF的认证机制时,以下设置必须是Python
Iterable
,否则get_authenticators()
将无法设置你的认证程序。
assert isinstance(settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'], collections.abc.Iterable)
如果将
AUTHENTICATION_CLASS
括在括号中,例如:
settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = (•••)
它并不像您想象的那样是一个元素
tuple
,而只是被视为另一个 Python 变量。单元素 tuple
是一个文字,例如:(•••,)
。因此正确的代码应该是:
settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = (•••,)
我的建议通常是尽可能使用
list
而不是 tuple
。