2012-01-17 8 views
18

Mi código funciona de abajo un poco, se crea el objeto de usuario y salva pero no guarda la contraseña:¿Cómo crear o registrar un usuario usando django-tastypie API mediante programación?

class CreateUserResource(ModelResource): 
    class Meta: 
     allowed_methods = ['post'] 
     object_class = User 
     authentication = Authentication() 
     authorization = Authorization() 
     include_resource_uri = False 
     fields = ['username'] 

    def obj_create(self, bundle, request=None, **kwargs): 
     try: 
      bundle = super(CreateUserResource, self).obj_create(bundle, request, **kwargs) 
     except IntegrityError: 
      raise BadRequest('That username already exists') 
     return bundle 

Si agrego 'contraseña' a los campos Meta entonces no guardar la contraseña en bruto, pero no hashing it. ¿Qué estoy haciendo mal?


Así que esto es lo que funcionó para mí:

def obj_create(self, bundle, request=None, **kwargs): 
    username, password = bundle.data['username'], bundle.data['password'] 
    try: 
     bundle.obj = User.objects.create_user(username, '', password) 
    except IntegrityError: 
     raise BadRequest('That username already exists') 
    return bundle 
+1

¿Cómo hacer la autenticación sin crear el usuario en primer lugar? – Burak

+0

Debe llamar a su clase UserResource en lugar de CreateUserResource para respetar los principios de REST. El hecho de que se usa solo para la creación ya se dice en el atributo allowed_methods, y podría agregarse en una docstring sobre su nombre de clase. –

+0

@DavidW. ¿Cómo lo haría si necesita diferentes métodos de autenticación para crear y listar? – antonagestam

Respuesta

21

Al crear un usuario necesita cualquiera de los métodos utilización set_password user.set_password(bundle.data.get('password')) o utilizar un método create_user del objeto Usuario.

user = User.objects.create_user(bundle.data.get('username'), bundle.data.get('email'), bundle.data.get('password')) 

Así que algo como esto podría funcionar para usted:

def obj_create(self, bundle, request=None, **kwargs): 
    try: 
     bundle = super(CreateUserResource, self).obj_create(bundle, request, **kwargs) 
     bundle.obj.set_password(bundle.data.get('password')) 
     bundle.obj.save() 
    except IntegrityError: 
     raise BadRequest('That username already exists') 
    return bundle 
+0

Escribí una publicación de blog en este http://www.psjinx.com/programming/2013/06/07/so-you-want-to -create-users-using-djangotastypie/ – pankaj28843

4

yo estaba en la misma situación y encontré ambas soluciones útiles, pero no completa. En ambos, pude crear usuarios con un nombre de usuario vacío. No quería tener tales filtraciones, así que esto es lo que hice.

En primer lugar, creó una forma de validación:

from django import forms 
from django.forms import ModelForm 
from django.contrib.auth.models import User 

class UserForm(forms.ModelForm): 
def __init__(self, *args, **kwargs): 
    super(UserForm, self).__init__(*args, **kwargs) 

    self.fields['username'].error_messages = {'required': "Please enter username"} 
    self.fields['username'].max_length = 30 
    self.fields['password'].error_messages = {'required': 'Please enter password'} 
    self.fields['password'].max_length = 30 

    self.fields['email'].required = False 

def clean_username(self): 
    username = self.cleaned_data['username'] 
    if len(username) < 4: 
     raise forms.ValidationError("Username has to be longer than 4 characters") 
    return username 

def clean_password(self): 
    password = self.cleaned_data['password'] 
    if len(password) < 5: 
     raise forms.ValidationError("Password has to be longer than 5 characters") 
    return password 

class Meta: 
    model = User 
    fields = ('username', 'email', 'password') 

Luego, dentro de la UserResource

validation = FormValidation(form_class=UserForm) 

def obj_create(self, bundle, request=None, **kwargs): 
    bundle = super(UserResource, self).obj_create(bundle, request, **kwargs) 
    bundle.obj.set_password(bundle.data.get('password')) 
    bundle.obj.save() 

    return bundle 

espero que mi solución puede ayudar a los compañeros desarrolladores. Feliz codificación!

2

Estaba tratando de usar un código similar con django-tastypie == 0.9.12 y me metí en errores con respecto al conjunto de preguntas faltantes y al número de argumentos para obj_create. Usando el siguiente código que funcionó para mí:

from django.contrib.auth.models import User 
from django.db import IntegrityError 

from tastypie.resources import ModelResource 
from tastypie.authorization import Authorization 
from tastypie.authentication import Authentication 
from tastypie import fields 
from tastypie.exceptions import BadRequest 

class UserSignUpResource(ModelResource): 
    class Meta: 
     object_class = User 
     resource_name = 'register' 
     fields = ['username', 'first_name', 'last_name', 'email'] 
     allowed_methods = ['post'] 
     include_resource_uri = False 
     authentication = Authentication() 
     authorization = Authorization() 
     queryset = User.objects.all() 

    def obj_create(self, bundle, request=None, **kwargs): 
     try: 
      bundle = super(UserSignUpResource, self).obj_create(bundle) 
      bundle.obj.set_password(bundle.data.get('password')) 
      bundle.obj.save() 
     except IntegrityError: 
      raise BadRequest('Username already exists') 

     return bundle 

Algunos código de prueba sería:

from django.contrib.auth.models import User 
from django.contrib.auth.hashers import check_password 

from tastypie.test import ResourceTestCase 

class UserSignUpResourceTest(ResourceTestCase): 
    def test_post_list(self): 
     post_arguments = { 
      "email": "[email protected]", 
      "first_name": "John", 
      "last_name": "Doe", 
      "username": "test-user", 
      "password": "idiotic-pwd" 
     } 
     # Check how many are there 
     self.assertEqual(User.objects.count(), 0) 
     self.assertHttpCreated(self.api_client.post('/api/register/', 
     format='json', data=post_arguments)) 
     # Check how many are there. Should be one more 
     self.assertEqual(User.objects.count(), 1) 
     # Check attributes got saved correctly 
     user = User.objects.get(username='test-user') 
     for atr in post_arguments: 
      if atr == 'password': 
       check_password(post_arguments[atr], getattr(user, atr)) 
      else: 
       self.assertEqual(post_arguments[atr], getattr(user, atr)) 
+0

Muchas gracias por esta publicación. Fue muy útil para obtener el recurso de registro de usuario creado para .9.12 –

Cuestiones relacionadas