way restful proper from framework ejemplo data creating create consumir consume django tastypie

restful - ¿Cómo crear o registrar un usuario utilizando la API django-tastypie mediante programación?



proper way to consume data from restful api in django (3)

Mi código a continuación funciona, crea el objeto Usuario y lo guarda pero no guarda la contraseña:

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 guarda la contraseña sin procesar pero no la hash. ¿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


Al crear un usuario, necesita utilizar el método set_password user.set_password(bundle.data.get(''password'')) o usar un método create_user del objeto User.

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

Así que algo como esto funcionaría para ti:

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


Estaba en la misma situación y encontré ambas soluciones útiles, pero no completas. En ambos, pude crear usuarios con un nombre de usuario vacío. No quería tener tales fugas, así que aquí está lo que hice.

Primero, creé un formulario 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 del 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 pueda ayudar a otros desarrolladores. ¡Feliz codificación!


Estaba intentando usar un código similar con django-tastypie == 0.9.12 y me metí en errores relacionados con el queryset faltante y la cantidad de argumentos para obj_create. Usando el siguiente código 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

Algún 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))