在 Djoser 和 Rest Framework 中使用自定义字段注册用户

Chu*_*lar 7 django python-3.x django-rest-framework

我正在尝试使用Djoser的“注册”端点。它工作正常,但我需要的字段不仅仅是“用户名”、“电子邮件”和“密码”。我已经看到了这个问题,确实我可以看到我想要的字段(在可浏览的 API 中)。但是当我尝试发布它时,我收到此错误

ImproperlyConfigured at /account/register/ 无法使用视图名称“user-detail”解析超链接关系的 URL。您可能没有在 API 中包含相关模型,或者错误地配置了lookup_field该字段的属性。

我不知道出了什么问题。

我的models.py 看起来是这样的:

from django.db import models


class User(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    email = models.CharField(max_length=100, blank=False)
    name = models.CharField(max_length=100, blank=False)
    last_name = models.CharField(max_length=100, blank=False)
    birthday = models.CharField(max_length=15, blank=False)
    password = models.CharField(max_length=100, blank=False)

    class Meta:
        ordering = ('created',)
Run Code Online (Sandbox Code Playgroud)

序列化程序.py

from rest_framework import serializers
from users.models import User


class UserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = User
        fields = ('url', 'id', 'email', 'name', 'last_name', 'birthday', 'password')
Run Code Online (Sandbox Code Playgroud)

我的意见.py

from users.models import User
from users.serializers import UserSerializer
from rest_framework import viewsets


class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
Run Code Online (Sandbox Code Playgroud)

在 settings.py 中我添加了:

DJOSER = {
    ...
    'SERIALIZERS': {
        'user_registration': 'users.serializers.UserSerializer',
    },
}
Run Code Online (Sandbox Code Playgroud)

编辑

应用程序/urls.py

from django.conf.urls import url, include
from users import views
from rest_framework.routers import DefaultRouter
from rest_framework.schemas import get_schema_view

# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'users', views.UserViewSet)

schema_view = get_schema_view(title='Pastebin API')

# The API URLs are now determined automatically by the router.
# Additionally, we include the login URLs for the browsable API.

urlpatterns = [
    url(r'^', include(router.urls)),
    url('^schema/$', schema_view),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
Run Code Online (Sandbox Code Playgroud)

api/urls.py

from django.conf.urls import url, include
from django.contrib import admin
from rest_framework_jwt import views as jwt_views
from rest_framework import routers

router = routers.DefaultRouter()

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include(router.urls)),
    url(r'^account/', include('djoser.urls')),
    url(r'^auth/login/', jwt_views.obtain_jwt_token, name='auth'),
]
Run Code Online (Sandbox Code Playgroud)

有人有想法吗?

ARK*_*han 5

您可以通过继承AbstractUser使用djoserdjango 2.0 中创建自定义用户,这会为您的应用程序创建一个新的用户模型,如下所示:

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    FUNCTION = 1
    VIEWER = 2
    TECHNICIAN = 3
    ROLE_CHOICES = (
        (FUNCTION, 'Functional'),
        (VIEWER, 'Viewer'),
        (TECHNICIAN, 'Technician'),
    )
    role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
    REQUIRED_FIELDS = ["email", "role"]
Run Code Online (Sandbox Code Playgroud)

然后在settings.py 中定义 user new User 类:AUTH_USER_MODEL = 'app_name.User'

请注意,这里我已经定义了我的 REQUIRED_FIELDS。因此,当我使用 djoser API /me/ 时,它将为我提供所有必填字段。


Dam*_*nic 1

例外情况很明显:Django 无法按user-detail名称解析 URL。它尝试这样做是因为您已经serializers.HyperlinkedModelSerializer使用一个url字段创建了一个扩展序列化器,该字段应该包含指向您的特定用户对象的链接。

我看到的问题是你的 mainurls.py不包含apiurl,而且它们都是重复的并且连接起来有点奇怪。我会重写它如下(假设你也有user应用程序):

urls.py

from django.conf.urls import url, include
from django.contrib import admin

from rest_framework.schemas import get_schema_view
from rest_framework_jwt import views as jwt_views

schema_view = get_schema_view(title='Pastebin API')

urlpatterns = [
    url('^schema/$', schema_view),
    url(r'^admin/', admin.site.urls),
    url(r'^user/', include('user.urls')),
    url(r'^account/', include('djoser.urls')),
    # Not sure if you need both:
    url(r'^auth/login/', jwt_views.obtain_jwt_token, name='auth'),
    url(
        r'^api-auth/',
        include('rest_framework.urls', namespace='rest_framework')),
]
Run Code Online (Sandbox Code Playgroud)

用户应用程序urls.py

from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter

from .views import UserViewSet

router = DefaultRouter()
router.register(r'users', UserViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
]
Run Code Online (Sandbox Code Playgroud)

我不确定为什么你需要另一个名为的应用程序api

如果没有帮助,请尝试查看这篇有关路由器命名空间的文章。