personalizados formularios form example avanzados python django django-forms registration profile

python - formularios - Django-Registration & Django-Profile, usando su propio formulario personalizado



login django (4)

Estoy haciendo uso de django-registration y django-profile para gestionar el registro y los perfiles. Me gustaría crear un perfil para el usuario en el momento del registro. Creé un formulario de registro personalizado y lo agregué a urls.py utilizando el tutorial sobre:

http://dewful.com/?p=70

La idea básica en el tutorial es anular el formulario de registro predeterminado para crear el perfil al mismo tiempo.

forms.py - En mi aplicación de perfiles

from django import forms from registration.forms import RegistrationForm from django.utils.translation import ugettext_lazy as _ from profiles.models import UserProfile from registration.models import RegistrationProfile attrs_dict = { ''class'': ''required'' } class UserRegistrationForm(RegistrationForm): city = forms.CharField(widget=forms.TextInput(attrs=attrs_dict)) def save(self, profile_callback=None): new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data[''username''], password=self.cleaned_data[''password1''], email=self.cleaned_data[''email'']) new_profile = UserProfile(user=new_user, city=self.cleaned_data[''city'']) new_profile.save() return new_user

En urls.py

from profiles.forms import UserRegistrationForm

y

url(r''^register/$'', register, {''backend'': ''registration.backends.default.DefaultBackend'', ''form_class'' : UserRegistrationForm}, name=''registration_register''),

Se muestra el formulario y puedo ingresar a la ciudad, sin embargo, no guarda ni crea la entrada en la base de datos.


Como se describe en mi comentario sobre el ticket de Django Trac hice una metaclase y mixin para permitir herencia múltiple para los ModelForm Django de ModelForm . Con esto, puede simplemente hacer un formulario que permita el registro con campos de usuarios y modelos de perfil al mismo tiempo sin campos de codificación rígida o repitiéndose usted mismo. Al usar mi metaclase y mixin (y también fieldset mixin) puedes hacer:

class UserRegistrationForm(metaforms.FieldsetFormMixin, metaforms.ParentsIncludedModelFormMixin, UserCreationForm, UserProfileChangeForm): error_css_class = ''error'' required_css_class = ''required'' fieldset = UserCreationForm.fieldset + [( utils_text.capfirst(UserProfileChangeForm.Meta.model._meta.verbose_name), { ''fields'': UserProfileChangeForm.base_fields.keys(), })] def save(self, commit=True): # We disable save method as registration backend module should take care of user and user # profile objects creation and we do not use this form for changing data assert False return None __metaclass__ = metaforms.ParentsIncludedModelFormMetaclass

Donde UserCreationForm puede ser, por ejemplo, django.contrib.auth.forms.UserCreationForm form y UserProfileChangeForm un simple ModelForm para su modelo de perfil. (No olvide establecer la editable en False en su clave externa para el modelo de User ).

Con django-registration backend teniendo dicho método de registro:

def register(self, request, **kwargs): user = super(ProfileBackend, self).register(request, **kwargs) profile, created = utils.get_profile_model().objects.get_or_create(user=user) # lambda-object to the rescue form = lambda: None form.cleaned_data = kwargs # First name, last name and e-mail address are stored in user object forms_models.construct_instance(form, user) user.save() # Other fields are stored in user profile object forms_models.construct_instance(form, profile) profile.save() return user

Tenga cuidado de que la señal de registro se envíe al comienzo de este método (en el método de la superclase) y no al final.

De la misma manera, puede hacer un formulario de cambio para la información del usuario y del perfil. Ejemplo de esto lo puedes encontrar en mi comentario sobre el ticket de Django Trac mencionado anteriormente.


Con registro 0.8 y posterior:

Cree una subclase de registration.backends.default.views.RegistrationView en su views.py o equivalente:

from registration.backends.default.views import RegistrationView class MyRegistrationView(RegistrationView): form_class= MyCustomRegistrationForm def register(self, request, **cleaned_data): new_user= super(MyRegistrationView, self).register(request, **cleaned_data) # here create your new UserProfile object return new_user


Estás a medio camino; has creado con éxito un formulario personalizado que reemplaza el formulario predeterminado. Pero está intentando hacer su procesamiento personalizado con un método save () en su formulario de modelo. Eso fue posible en versiones anteriores de django-registration, pero puedo ver por el hecho de que usted especificó un back-end en su URL conf que está usando v0.8.

La guía de actualización dice:

Anteriormente, se esperaba que el formulario utilizado para recopilar datos durante el registro implementara un método save () que crearía la nueva cuenta de usuario. Este ya no es el caso; la creación de la cuenta es manejada por el backend, por lo que cualquier lógica personalizada debe moverse a un backend personalizado o al conectar listeners a las señales enviadas durante el proceso de registro.

En otras palabras, el método save () en el formulario se ignora ahora que está en la versión 0.8. Debe hacer su procesamiento personalizado con un back-end personalizado o con una señal. Elegí crear un back-end personalizado (si alguien ha conseguido que esto funcione con las señales, por favor, publique el código; no pude hacerlo funcionar de esa manera). Debería poder modificar esto para guardar en su perfil personalizado.

  1. Crea un regbackend.py en tu aplicación.
  2. Copie el método register () de DefaultBackend en él.
  3. Al final del método, haga una consulta para obtener la instancia de usuario correspondiente.
  4. Guarde los campos de formulario adicionales en esa instancia.
  5. Modifique la configuración de URL para que apunte TANTO al formulario personalizado Y al back-end personalizado

Entonces la URL conf es:

url(r''^accounts/register/$'', register, {''backend'': ''accounts.regbackend.RegBackend'',''form_class'':MM_RegistrationForm}, name=''registration_register'' ),

regbackend.py tiene las importaciones necesarias y es básicamente una copia de DefaultBackend con solo el método register () y la adición de:

u = User.objects.get(username=new_user.username) u.first_name = kwargs[''first_name''] u.last_name = kwargs[''last_name''] u.save()