【问题标题】:DRF throw django.core.exceptions.ImproperlyConfigured when override get_queryset覆盖 get_queryset 时 DRF 抛出 django.core.exceptions.ImproperlyConfigured
【发布时间】:2020-05-29 09:36:56
【问题描述】:

Django Rest 框架抛出:

django.core.exceptions.ImproperlyConfigured:无法使用视图名称“customuser-detail”解析超链接关系的 URL。您可能没有在 API 中包含相关模型,或者在此字段上错误地配置了 lookup_field 属性。

当我尝试 覆盖 get_queryset 时。 我的用户序列化器:


class UserSerializer(serializers.HyperlinkedModelSerializer):
    """
    Represent User Serializer class.
    """
    teacher_account = TeacherSerializer(required=False)
    student_account = StudentSerializer(required=False)

    account_type = serializers.IntegerField(required=True)

    class Meta:
        model = CustomUser
        fields = ['url', 'username', "password", 'email', 'first_name', 'last_name', "account_type", 'teacher_account', 'student_account']

        email_validator = UniqueValidator(queryset=CustomUser.objects.all(), message="A user with that email already exists.")

        extra_kwargs = {
            "password": {"write_only": True},
            "email": {"required": True, "validators": [email_validator]}
        }

    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related('teacher_account', 'student_account')
        return queryset

用户/模型.py:

class StudentAccount(models.Model):
    """
    Represent student's account model.

    """
    classes = models.ManyToManyField('classroom.Class', related_name="students")


class TeacherAccount(models.Model):
    """
    Represent teacher's account.

    use get_subject_name from {root}/utils.py for get name of the subject.
    """

    subject_id = models.PositiveSmallIntegerField("Предмет", choices=SUBJECTS_CHOICES, blank=False, default=0)


class CustomUser(AbstractUser):
    """
    Represent Custom user model, inherited from AbstractUser

    account_type = 0(teacher) or 1(student)
    """
    student_account = models.OneToOneField(StudentAccount, on_delete=models.CASCADE, blank=True, null=True, related_name="user")
    teacher_account = models.OneToOneField(TeacherAccount, on_delete=models.CASCADE, blank=True, null=True, related_name="user")

    account_type = models.PositiveSmallIntegerField(default=1)

    first_name = models.CharField("-", max_length=30, blank=False)
    last_name = models.CharField("-", max_length=150, blank=False)

我的意见.py:

class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """

    permission_classes = (permissions.AllowAny,)
    # queryset = CustomUser.objects.all()
    # queryset_raw = CustomUser.objects.all()
    # queryset = UserSerializer.setup_eager_loading(queryset_raw)
    model = CustomUser
    serializer_class = UserSerializer

    def get_queryset(self):
        queryset = CustomUser.objects.all()
        # queryset = self.get_serializer_class().setup_eager_loading(queryset)
        return queryset

我的 urls.py:

from django.urls import path, include

from rest_framework import routers
from knox import views as knox_views

from .views import UserViewSet, ClassViewSet, LoginView, LessonViewSet

router = routers.DefaultRouter()
router.register('users', UserViewSet, basename="CustomUser")
router.register('classes', ClassViewSet)
router.register('lessons', LessonViewSet)


urlpatterns = [
    path('login/', LoginView.as_view(), name='knox-login'),
    path('logout/', knox_views.LogoutView.as_view(), name="knox_logout"),
    path('logoutall/', knox_views.LogoutAllView.as_view(), name="knox_logoutall"),
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

我意识到,如果我将覆盖显示用户模型详细信息的页面的 url,则可以修复它。但我认为有更正确的答案。

path('api/users/<int:pk>/', UserViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"}), name="customuser-detail")

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    根据documentation,您在向路由器注册ViewSet 时提供的basename 将用于生成URL 模式。您提供了basename=CustomUser,它有大写​​。

    正如错误所指出的(另请参阅documentation,了解如何确定超链接视图和构建默认名称)您的基本名称应该是小写的。

    如果您想保持大写,请参阅之前的文档链接以在 HyperlinkedModelSerializer 上实现自定义 view_name='CustomUser-detail'

    【讨论】:

    • 嗨!它对我有用,谢谢。这个问题被证明是愚蠢的。我不知道 Django URL 是这样工作的。此外,由我的序列化程序中的lookup_field 引起的错误。谢谢你的链接,我不知道为什么我没有使用文档)
    猜你喜欢
    • 2020-10-07
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    • 2019-07-07
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多