2010-04-08 2 views
30

Я использую django-registration и django-profile для обработки регистрации и профилей. Я хотел бы создать профиль для пользователя во время регистрации. Я создал пользовательский регистрационную форму, и добавил, что в urls.py используя учебник по:Django-Registration & Django-Profile, используя вашу собственную форму

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

Основная идея в учебнике переопределить форму регистрации по умолчанию, чтобы создать профиль, в то же время.

forms.py - В моем профилях приложение отображается

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 

В urls.py

from profiles.forms import UserRegistrationForm 

и

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

форма, и я могу войти в Сити, однако он не сохраняет и не создает запись в БД.

ответ

28

Вы на полпути - вы успешно создали пользовательскую форму, которая заменяет форму по умолчанию. Но вы пытаетесь выполнить свою собственную обработку с помощью метода save() в своей модельной форме. Это было возможно в более ранних версиях django-регистрации, но я вижу, что вы указали бэкэнд в своем URL-conf, что используете v0.8.

The upgrade guide говорит:

Ранее форма используется для сбора данных при регистрации Ожидалось для реализации способа сохранения(), который бы создать новую учетную запись пользователя. Это уже не так; создавая , учетная запись обрабатывается бэкэнд, , поэтому любая пользовательская логика должна быть переведена в пользовательский бэкэнд или на , соединяющий слушателей с сигналами , отправленными во время процесса регистрации.

Другими словами, метод save() в форме игнорируется теперь, когда вы находитесь на версии 0.8. Вам необходимо выполнить свою собственную обработку либо с помощью пользовательского бэкэнд, либо с помощью сигнала. Я решил создать пользовательский back-end (если кто-то получил эту работу с сигналами, пожалуйста, отправьте код - я не смог заставить его работать таким образом). Вы должны иметь возможность изменить это, чтобы сохранить свой настраиваемый профиль.

  1. Создайте файл regbackend.py в своем приложении.
  2. Скопируйте метод register() из DefaultBackend в него.
  3. В конце метода выполните запрос, чтобы получить соответствующий экземпляр пользователя.
  4. Сохраните дополнительные поля формы в этом экземпляре.
  5. Измените URL конф так, что он указует на ОБА пользовательской форму и обычай фонового

Так URL конф является:

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

regbackend.py обладает необходимым импортом и в основном копия DefaultBackend только с методом регистра(), и добавление:

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

спасибо за комментарий. Решил сделать перенаправление для создания профиля при регистрации, таким образом у вас нет профиля для неактивного пользователя. Отметьте этот вопрос, как ответ. – ismail

+0

У меня такая же проблема с новой версией регистрации djando. Shacker, но где именно: «Скопируйте метод register() из DefaultBackend в него». DefaultBackend ??, где есть? Спасибо – Asinox

+2

Asinox - вам нужно получить его из исходного кода регистрации django. Посмотрите в регистрации/backends/default/__ init__.py – shacker

8

Solution with signals - здесь я написал, как использовать сигналы для сохранения Адди данные

+0

Отличный, простой способ сделать это! –

+0

Мне это нравится, но это можно сделать еще проще, так как вам не нужно вводить функцию «заполнение профиля» и вызов 'connect()' в отдельный файл (имя 'regbackend.py' также может быть немного вводящим в заблуждение, так как вы не создаете бэкэнд) – Agos

+0

Угадайте, спасибо за ответ! – dmitko

10

Как описано в my comment on Django Trac ticket Я сделал метакласс и смесь, чтобы разрешить множественное наследование для форм ModelForm Django. С помощью этого вы можете просто создать форму, которая позволяет одновременно регистрировать поля из моделей пользователей и профилей без полей жесткого кодирования или повторять себя. Используя мой метакласс и подмешать (а также Fieldset подмешать) вы можете сделать:

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 может быть, например, django.contrib.auth.forms.UserCreationForm формы и UserProfileChangeForm простого ModelForm для вашей модели профиля. (Не забудьте установить editable в False в вашем внешнем ключе для User модели.)

С Джанго-регистрации бэкэндом имея такой метод регистра:

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 

Будьте осторожны, что регистрация сигнала отправить в начале этот метод (в методе в суперклассе), а не в конце.

Таким же образом вы можете внести изменения для информации о пользователе и профиле. Пример этого вы можете найти в моем комментарии к билету Django Trac, упомянутому выше.

+1

Я недавно реализовал то же самое с сигналами, но это просто потрясающе! Мне определенно нужно научиться использовать метаклассы и методы микширования! –

+1

Я рад, что вам это нравится. ;-) – Mitar

+0

Какой импорт мне нужен, чтобы сделать эту работу? – stanwise

1

С регистрации 0.8 и более поздних версий:

Создать подкласс registration.backends.default.views.RegistrationView в вашем views.py или эквивалент:

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