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

时间:2017-01-10 22:12:56

标签: django python-3.x django-rest-framework

我试图使用"注册"来自Djoser的端点。它工作正常,但我需要更多的字段而不仅仅是"用户名","电子邮件"和#34;密码"。 我已经看到了这个question,实际上我可以看到我想要的字段(在可浏览的API中)。但是当我尝试发布它时,我收到了这个错误

  

在/ account / register /处不正确配置无法解析URL   对于使用视图名称" user-detail"的超链接关系。你可以   未能在您的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',)

serializers.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')

my views.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

并在settings.py中添加了:

DJOSER = {
    ...
    'SERIALIZERS': {
        'user_registration': 'users.serializers.UserSerializer',
    },
}

修改

应用/ 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'))
]

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'),
]

有人有想法吗?

2 个答案:

答案 0 :(得分:1)

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

我看到的问题是您的主urls.py不包含api个网址,而且它们都是重复的,并且有点奇怪。我会按如下方式重写它(假设你还有user app):

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')),
]

用户应用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)),
]

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

如果没有帮助,请尝试在namespacing the router上查看此文章。

答案 1 :(得分:1)

您可以使用 djoser django 2.0 中创建自定义用户,方法是继承 AbstractUser ,从而针对您的用户创建新的用户模型这样的应用:

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"]

,然后在 settings.py 中定义用户新的User类: AUTH_USER_MODEL ='app_name.User'

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