繁体   English   中英

Django Rest Framework用户注册带有额外字段

[英]Django Rest Framework User Registrations with extra fields

我正在尝试使用DRF来允许用户通过我的API创建新的用户帐户。 我有一些要求可能与常规不同

  1. 成功创建后,它需要使用DRF的令牌功能返回用户令牌
  2. 所有POST'd字段都需要进行验证
  3. 我希望能够发布将存储在配置文件模型中的用户电话号码。
  4. 名字,姓氏,电子邮件地址和电话号码必须是必填字段

到目前为止,我想出了这个,但我收到一条错误消息,说“列'user_id'不能为空”

视图

@api_view(['POST'])
@permission_classes((AllowAny,))
def register_user(request):
    serialized = UserSerializer(data=request.DATA)
    if serialized.is_valid():
        user = User.objects.create_user(
            email = serialized.init_data['email'],
            username = serialized.init_data['username'],
            password = serialized.init_data['password'],
            first_name = serialized.init_data['first_name'],
            last_name = serialized.init_data['last_name']
        )

        phone_number = request.DATA["phone_number"]  
        #save phone_number to profile model here

        return Response(serialized.data['token'], status=status.HTTP_201_CREATED)
    else:
        return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)

串行

class UserSerializer(serializers.ModelSerializer):
    token = serializers.SerializerMethodField('get_token')

    class Meta:
        model = User
        fields = ('password', 'username', 'first_name', 'last_name', 'email', 'token', 'phone_number')


    def get_token(self, obj):
        token = Token.objects.create(user=obj)
        return token.key

我的问题是

  1. 我如何让这个工作?
  2. 我是否需要对电话号码,first_name,last_name,电子邮件进行单独验证以确保它们是必需的或由模型处理?
  3. 这是处理电话号码POST的正确方法吗?
  4. 这样安全吗? 如果没有,我该怎么做才能让它更安全?

堆栈跟踪

Django Version: 1.6.8
Python Version: 2.7.5
Installed Applications:
('django.contrib.sites',
 'django.contrib.admin',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'my_app',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'allauth.socialaccount.providers.facebook',
 'debug_toolbar',
 'rest_framework',
 'rest_framework.authtoken',
 'django_extensions')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware')


Traceback:
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  112.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  57.         return view_func(*args, **kwargs)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  403.             response = self.handle_exception(exc)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  400.             response = handler(request, *args, **kwargs)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/rest_framework/decorators.py" in handler
  50.             return func(*args, **kwargs)
File "/home/vagrant/projects/my_project/my/my_app/api/views.py" in register_user
  60.         return Response(serialized.data['token'], status=status.HTTP_201_CREATED)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/rest_framework/serializers.py" in data
  572.                 self._data = self.to_native(obj)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/rest_framework/serializers.py" in to_native
  351.             value = field.field_to_native(obj, field_name)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/rest_framework/fields.py" in field_to_native
  1041.         value = getattr(self.parent, self.method_name)(obj)
File "/home/vagrant/projects/my_project/my/my_app/api/serializers.py" in get_token
  19.         token = Token.objects.create(user=obj)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/manager.py" in create
  157.         return self.get_queryset().create(**kwargs)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/query.py" in create
  322.         obj.save(force_insert=True, using=self.db)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/rest_framework/authtoken/models.py" in save
  33.         return super(Token, self).save(*args, **kwargs)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/base.py" in save
  545.                        force_update=force_update, update_fields=update_fields)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/base.py" in save_base
  573.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
  654.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
  687.                                using=using, raw=raw)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/manager.py" in _insert
  232.         return insert_query(self.model, objs, fields, **kwargs)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/query.py" in insert_query
  1514.     return query.get_compiler(using=using).execute_sql(return_id)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  903.             cursor.execute(sql, params)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/debug_toolbar/panels/sql/tracking.py" in execute
  174.         return self._record(self.cursor.execute, sql, params)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/debug_toolbar/panels/sql/tracking.py" in _record
  104.             return method(sql, params)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/backends/util.py" in execute
  69.             return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/backends/util.py" in execute
  53.                 return self.cursor.execute(sql, params)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/backends/mysql/base.py" in execute
  129.                 six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
File "/home/vagrant/envs/my/lib/python2.7/site-packages/django/db/backends/mysql/base.py" in execute
  124.             return self.cursor.execute(query, args)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/MySQLdb/cursors.py" in execute
  205.             self.errorhandler(self, exc, value)
File "/home/vagrant/envs/my/lib/python2.7/site-packages/MySQLdb/connections.py" in defaulterrorhandler
  36.     raise errorclass, errorvalue

Exception Type: IntegrityError at /api/user/register/
Exception Value: (1048, "Column 'user_id' cannot be null")

我建议在Django REST Framework中使用基于类的视图。 它们为您提供了许多基于功能的视图所缺少的额外功能,并且它们受到更多支持。 虽然这对于这种情况不太重要 ,但这也是一个非常基本的情况,它避免了Django REST Framework带来的大部分内容。

我是否需要对电话号码,first_name,last_name,电子邮件进行单独验证以确保它们是必需的或由模型处理?

当您调用serializer.is_valid检查以确保包含模型上指定的任何字段。 尝试一下,如果没有发生,请确保在任何字段上都没有指定empty=False 如果您无法解决此问题,可以覆盖序列化程序中的字段并在那里设置required=True

这是处理电话号码POST的正确方法吗?

序列化程序可以通过调用serializer.save()自动创建用户。 如果您需要在create_user管理器中使用自定义逻辑,那么您可能无法使用save

这样安全吗? 如果没有,我该怎么做才能让它更安全?

Django会在这里帮到你很多 ,所以你的代码目前看起来很不错。 您可能想要考虑的一件事是序列化器的init_datarequest.DATA中的init_data相同。 你应该从serializer.object访问经过验证的数据(比如serializer.object.username ,因为任何验证器都可能修改了你的数据,使它对Django ORM更友好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM