Django-Inscription & Django-Profile, à l'aide de votre propre formulaire personnalisé

j'utilise django-registration et django-profile pour gérer l'enregistrement et les profils. Je voudrais créer un profil pour l'utilisateur au moment de l'inscription. J'ai créé un formulaire d'inscription personnalisé, et ajouté que urls.py utiliser le tutoriel sur:

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

L'idée de base dans le tutoriel est de remplacer la valeur par défaut formulaire d'inscription pour créer le profil en même temps.

forms.py - Dans mon des profils d'application

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
<!--3 - urls.py

from profiles.forms import UserRegistrationForm

et

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

le formulaire est affiché, et je peux entrer en ville, cependant il ne sauve pas ou ne crée pas l'entrée dans le DB.

31
demandé sur Serjik 2010-04-08 20:05:30

4 réponses

Vous êtes à mi-chemin - vous avez créé un formulaire personnalisé qui remplace le formulaire par défaut. Mais vous essayez de faire votre traitement personnalisé avec une méthode save() sur votre formulaire modèle. C'était possible dans les versions plus anciennes de django-registration, mais je peux voir du fait que vous avez spécifié un backend dans votre conf URL que vous utilisez v0.8.

guide de mise à niveau dit:

Auparavant, le formulaire utilisé pour recueillir des données au cours de l'inscription était attendue pour implémenter une méthode save () qui créerait le nouveau compte d'utilisateur. Ce n'est plus le cas; la création de le compte est géré par le backend, et donc, une logique personnalisée devrait être transféré dans un backend personnalisé, ou par connexion auditeurs les signaux envoyé lors de l'inscription.

En d'autres termes, la méthode save() sur le formulaire est ignoré maintenant que vous êtes sur la version 0.8. Vous devez faire votre traitement personnalisé soit avec un backend, ou avec un signal. J'ai choisi de créer un back-end personnalisé (si quelqu'un a obtenu ce travail avec des signaux, s'il vous plaît post code - je n'ai pas été en mesure de le faire fonctionner de cette façon). Vous devriez être capable de le modifier pour enregistrer votre profil personnalisé.

  1. Créer un regbackend.py dans votre application.
  2. Copier la méthode register() de DefaultBackend.
  3. À la fin de la méthode, de faire une requête pour obtenir l'Utilisateur correspondant instance.
  4. Sauvegardez les champs additionnels du formulaire dans cette instance.
  5. modifiez le conf URL pour qu'il pointe à la fois vers la forme personnalisée et vers la fin

donc le conf URL est:

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

regbackend.py a les importations nécessaires et est essentiellement une copie de DefaultBackend avec juste la méthode register (), et l'ajout de:

    u = User.objects.get(username=new_user.username)
    u.first_name = kwargs['first_name']
    u.last_name = kwargs['last_name']
    u.save() 
29
répondu shacker 2010-04-22 00:59:37

Comme décrit dans mon commentaire sur Django Trac billet j'ai fait une métaclasse et mixin pour permettre l'héritage multiple pour ModelForm formulaires Django. Avec cela, vous pouvez simplement faire un formulaire qui permet l'enregistrement avec des champs de l'utilisateur et des modèles de profil en même temps sans champs de codage dur ou se répéter. En utilisant mon métaclasse et mixin (et aussi fieldset mixin) vous pouvez faire:

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

UserCreationForm peut être, par exemple,django.contrib.auth.forms.UserCreationForm formulaire UserProfileChangeForm un simple ModelForm pour votre modèle de profil. (Ne pas oublier de mettre editableFalse dans votre clé étrangère User modèle.)

Avec django-enregistrement backend avoir une telle méthode register:

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

attention que le signal d'enregistrement soit envoyé au début de cette méthode (dans la méthode en superclasse) et non à la fin.

de la même manière, vous pouvez faire un formulaire de modification pour les informations utilisateur et profil. Exemple pour ceci vous pouvez trouver dans mon commentaire sur Django Trac ticket mentionné ci-dessus.

11
répondu Mitar 2015-08-11 09:44:28

la Solution avec des signaux - ici j'ai écrit comment utiliser des signaux pour sauver des données supplémentaires

8
répondu dmitko 2010-06-01 05:59:03

Avec l'enregistrement de 0,8 et plus tard:

créer une sous-classe d'enregistrement.backends.défaut.vue.RegistrationView dans votre views.py ou l'équivalent:

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
1
répondu tzot 2014-05-21 12:16:26