Django-Rejestracja & Django-profil, używając własnego, niestandardowego formularza

Używam django-registration i django-profile do obsługi rejestracji i profili. Chciałbym utworzyć profil użytkownika w momencie rejestracji. Stworzyłem niestandardowy formularz rejestracyjny i dodałem, że do urls.py korzystanie z samouczka na:

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

Podstawową ideą w samouczku jest zastąpienie domyślnego formularza rejestracyjnego, aby utworzyć profil w tym samym czasie.

Forms.py -w moich profilach app

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

W urls.py

from profiles.forms import UserRegistrationForm

I

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

Formularz jest wyświetlany i mogę wejść w City, jednak nie zapisuje ani nie tworzy wpisu w DB.

Author: Serjik, 2010-04-08

4 answers

Jesteś w połowie drogi - pomyślnie zbudowałeś niestandardowy formularz, który zastępuje domyślny formularz. Ale próbujesz wykonać niestandardowe przetwarzanie za pomocą metody save() w formularzu modelu. Było to możliwe w starszych wersjach django-registration, ale widzę po tym, że podałeś backend w konfie URL, którego używasz v0. 8.

Poradnik aktualizacji mówi:

Poprzednio, formularz używany do zbierania danych podczas rejestracji oczekiwano aby zaimplementować metodę save (), która utworzy nowe konto użytkownika. Tak już nie jest; tworzenie konto jest obsługiwane przez backend, i tak każda niestandardowa logika powinna być przeniesiony do niestandardowego backendu lub przez Podłączanie słuchaczy do sygnałów wysłane podczas procesu rejestracji.

Innymi słowy, metoda save() w formularzu jest ignorowana teraz, gdy używasz wersji 0.8. Musisz wykonać niestandardowe przetwarzanie za pomocą niestandardowego backendu lub za pomocą sygnał. Zdecydowałem się stworzyć niestandardowy back-end (jeśli ktoś ma to działa z sygnałami, proszę kod pocztowy - nie byłem w stanie to działa w ten sposób). Powinieneś być w stanie zmodyfikować to, aby zapisać w swoim niestandardowym profilu.

  1. Create a regbackend.py w aplikacji.
  2. Skopiuj do niej metodę register() z DefaultBackend.
  3. na końcu metody wykonaj zapytanie, aby uzyskać odpowiednią instancję użytkownika.
  4. Zapisz dodatkowe pola formularza do tego przykład.
  5. zmodyfikuj konf URL tak, aby wskazywał zarówno na niestandardowy formularz, jak i Niestandardowy back-end

Więc adres URL to:

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

Regbackend.py posiada niezbędne importy i jest w zasadzie kopią DefaultBackend z tylko metodą register () i dodaniem:

    u = User.objects.get(username=new_user.username)
    u.first_name = kwargs['first_name']
    u.last_name = kwargs['last_name']
    u.save() 
 29
Author: shacker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-22 00:59:37

Jak opisano w mój komentarz do Django Trac ticket zrobiłem metaclass i mixin, aby umożliwić wielokrotne dziedziczenie dla ModelForm form Django. Dzięki temu możesz po prostu utworzyć formularz, który umożliwia rejestrację z polami z modeli użytkowników i profili w tym samym czasie bez twardych pól kodowania lub powtarzania się. Za pomocą My metaclass i mixin (a także fieldset mixin) możesz zrobić:

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

Gdzie UserCreationForm może być na przykład django.contrib.auth.forms.UserCreationForm formularzem i UserProfileChangeForm prostym ModelForm dla Twojego profilu model. (Nie zapomnij ustawić editable na False w kluczu obcym do modelu User.)

Z backendem django-registration posiadającym taką metodę rejestru:

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

Należy uważać, aby sygnał rejestracyjny był wysyłany na początku tej metody (w metodzie w superclass), a nie na końcu.

W ten sam sposób możesz utworzyć formularz zmiany zarówno dla informacji o użytkowniku, jak i profilu. Przykład na to można znaleźć w moim komentarzu na Django Trac ticket wspomnianym powyżej.

 11
Author: Mitar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-11 09:44:28

Rozwiązanie z sygnałami - tutaj napisałem jak używać sygnałów do zapisywania dodatkowych danych

 8
Author: dmitko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-01 05:59:03

Z rejestracją 0.8 i Później:

Utwórz podklasę rejestracji.backends.default.widoki.Rejestracja w Twoim views.py "or equivalent": {]}

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
Author: tzot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 12:16:26