Уведомления

Группа в Telegram: @pythonsu

#1 Май 20, 2014 12:53:50

Mike67
Зарегистрирован: 2014-05-14
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу пояснить код

Добрый день, господа форумчане!
Как вы наверняка догадались, я начинающий джанго-программист. Прочитал книгу Django подробное руководство. Выполнил тутор с сайта. Теперь пытаюсь сделать простенький собственный проект в качестве обучения.
Возникают вопросы, ответы на которые найти “легко” не получается. Проясните пожалуйста, если вас не затруднит.

Первые вопросы по форме создания пользователя UserCreationForm. Если экземпляр этого класса вывести в шаблон сразу, то шаблон отобразит три поля, ник и два пароля. Если же этот класс переопределить так (именно так в три строчки):

class UserCreateForm(UserCreationForm):
	class Meta:
		model = User
то экземпляр нового класса в шаблон выводит кучу полей соответсвующих классу User.
Вопрос 1: чем принципиально отличается в этом случае класс наследник от родителя, что так по разному отражается в шаблоне?

Основной локальной целью является система логирования по email. Я согласно примерам из этих наших интернетов дописываю наследника так и это работает как ожидалось:
class UserCreateForm(UserCreationForm):
	email = forms.EmailField(required = True, error_messages = {'invalid': 'Введите корректный адрес электронной почты'})
	class Meta:
		model = User
		fields = ( "username", "email")
	def save(self, commit = True):
		user = super(UserCreationForm, self).save(commit = False)
		user.email = self.cleaned_data["email"]
		if commit:
			user.save()
		return user
но есть вопросы:
Вопрос 2 Зачем тут нужна перегрузка save? Без этой перегрузки форма так же “хорошо” на взляд новичка создает пользователя, проверяя данные поля email.
Вопрос 3 Почему если убрать параметр error_messages = {'invalid': ‘Введите корректный адрес электронной почты’} , некореектно введенное поле email приводит к сообщению “Введите правильное имя”? из за этого пришлось явно указать строку для ключа invalid

Заранее спасибо за пояснения, а то я неуютно себя чувствую не очень понимая что происходит, не смотря на то, что все работает как ожидается.


Отредактировано Mike67 (Май 20, 2014 13:06:07)

Офлайн

#2 Май 20, 2014 13:12:57

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Прошу пояснить код

Ответ 0: Для джанги есть соответсвующая ветка форума
Ответ 1: Метой же
Ответ 2: Этот код вообще некорректен, def save помещенный в Meta работать не будет, если сделать по-нормальному, то очевидно, что email Вы отделили от пользователя, вынеся его самостоятельным филдом, теперь надо назад поставить в соответствие.



Офлайн

#3 Май 20, 2014 13:28:13

Mike67
Зарегистрирован: 2014-05-14
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу пояснить код

FishHook
Ответ 0: Для джанги есть соответсвующая ветка форумаОтвет 1: Метой жеОтвет 2: Этот код вообще некорректен, def save помещенный в Meta работать не будет, если сделать по-нормальному, то очевидно, что email Вы отделили от пользователя, вынеся его самостоятельным филдом, теперь надо назад поставить в соответствие.
0: ой да промахнулся, Модераторам послал просьбу перекинуть
1: это я заметил, как я понимаю эта мета говорит что для нового класса используется модель User. а для родителя разве использовался другой?
2: это я опечатался при переносе кода сюда, поправил… save не в мете, а на уровень выше. и тут вопрос, если этот “привод в соотвевие” убрать вообще пользователь также прекрасно вноситься в базу с полем email. Так зачем приводить в соответвие?

Отредактировано Mike67 (Май 20, 2014 13:29:25)

Офлайн

#4 Май 20, 2014 13:39:36

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Прошу пояснить код

1. В у Меты помимо модели есть куча других параметров. Ну, например

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ('name', 'title', 'birth_date')
        labels = {
            'name': _('Writer'),
        }
        help_texts = {
            'name': _('Some useful help text.'),
        }
        error_messages = {
            'name': {
                'max_length': _("This writer's name is too long."),
            },
        }
Особенно обрати внимание на fields и exclude

2. У модели юзера есть email. Ты делаешь форму на основании модели. Но (!!!) поле email ты переопределил (самая первая строка класса), поэтому Джанга думает, что это не поле модели, а какое-то твое дополнительное. Поэтому при сейве нужно руками его засовывать.



Офлайн

#5 Май 20, 2014 14:17:43

Mike67
Зарегистрирован: 2014-05-14
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу пояснить код

Спасибо за ответы
1) C метой стало яснее. грубо говоря метой сбросил я настройки по умолчанию
2) Ответ я понял дословно. Но вот что практически я получаю:
Мое представление:

def register(request):
	form = UserCreateForm(request.POST or None)
	if form.is_valid():
		username = form.clean_username()
		password = form.clean_password2()
		form.save()
		user = authenticate(username = username, password = password)
		#return render_to_response("printerror.html", locals())
		if user.is_active:
			login(request, user)
		return HttpResponseRedirect('/')
	return render_to_response("register.html", {'form':form}, context_instance = RequestContext(request))

Моя форма:
class UserCreateForm(UserCreationForm):
	email = forms.EmailField(required = True, error_messages = {'invalid': 'Введите корректный адрес электронной почты'})
	class Meta:
		model = User
		fields = ( "username", "email")
	#def save(self, commit = True):
	#	user = super(UserCreationForm, self).save(commit = False)
	#	user.email = self.cleaned_data["email"]
	#	if commit:
	#	user.save()
	#	return user
С закоментированным save
Результатом работы является новый юзер в базе данных с правильным, внессеным email!. Я его вижу через админку. Плюс представление идентифицирует пользователя (до закоменченной строки в представлении) и логинит его без ошибок - Это я тоже вижу index.html ( HttpResponseRedirect('/')) выводит мне имя нового залогинненого пользователя.
Те каким-то образом Джанга понимает, что email не просто “мое дополнительное поле”, а использует его как поле модели.

Как только я раскоменчиваю save я получаю authenticate(username = username, password = password) == None . Пользователь при этом создается и по настройкам (тем что я вижу в админке) ничем не отличается от пользователя созданного без save. При этом второй почему-то не проходит аутентификацию. При этом логин и пароль в authenticate поступают правильные (вывожу через закоменченый printerror.html).

также второго пользователя (в отличии от первого) не может аутентифицировать и объект AuthenticationForm:
form = AuthenticationForm(data = request.POST)
	if form.is_valid():
		user = form.get_user()
		if user.is_active:
			login(request, user)
		return HttpResponseRedirect('/')
	return render_to_response('login.html', {'form':form}, context_instance = RequestContext(request))

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

Отредактировано Mike67 (Май 20, 2014 14:34:03)

Офлайн

#6 Май 20, 2014 16:36:10

Mike67
Зарегистрирован: 2014-05-14
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Прошу пояснить код

с проблемой аутентификации разобрался. Работает и с save и без него, без видимых отличий- отсюда и не понятно зачем он нужен.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version