首页 文章

Django Rest Framework用户注册额外字段

提问于
浏览
3

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

  • 成功创建后,它需要使用DRF的令牌功能返回用户令牌

  • 所有POST'd字段都需要验证

  • 我希望能够发布将存储在配置文件模型中的用户电话号码 .

  • 名字,姓氏,电子邮件地址和电话号码是必填字段

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

View

@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)

Serializer

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

我的问题是

  • 我如何使这个工作?

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

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

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

Stacktrace

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

1 回答

  • 1

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

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

    当您调用 serializer.is_valid 时,应检查以确保包含模型上指定的任何字段 . 尝试一下,如果它没有't happening make sure that you don'在任何字段上指定 empty=False . 如果您无法解决此问题,可以覆盖序列化程序上的字段并在那里设置 required=True .

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

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

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

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

相关问题