Делаем, как прописано в мануалах Django. Определяем модель, расширяющую django.contrib.auth.models.User:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
# необходимое поле для связки со встроенной моделью юзера Django
user = models.ForeignKey(User, unique=True)
# наше добавляемое поле
about = models.TextField(blank=True)
ну и сохраняем этот класс в свой models.py
В settings.py проекта прописываем параметр AUTH_PROFILE_MODULE, который позволит обращаться к нашей расширенной модели через вызов метода .get_profile у встроенной модели django.contrib.auth.models.User.
AUTH_PROFILE_MODULE = 'models.UserProfile'
В принципе, модель готова. Теперь (например) в шаблонах можно использовать такую конструкцию для вывода нашего поля about:
{{ user.get_profile.about }}
Только не забудьте для такого шаблона использовать RequestContext вместо Context, и подключить соотв.процессор контекста в settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
...
'django.contrib.auth.context_processors.auth',
...
)
Дальше нужно писать представления для просмотра/редактирования/создания/списка наших профайлов. Но лень.
Берем маленькое приложение Django под названием profiles вот тут, распаковываем архив, копируем каталог profiles в каталог, включенный в sys.path. (для таких случаев у меня есть каталог django_apps).
Подключаем это приложение в urls.py своего проекта:
urlpatterns = patterns('',
...
(r'^profiles/', include('profiles.urls')),
...
)
и в settings.py:
INSTALLED_APPS = (
...
'profiles',
)
Добавляем таблицы этого приложения и свою таблицу профайлов в базу:
[~]$ python manage.py syncdb
Осталось сделать шаблоны. Приложение profiles использует четыре штуки. Их имена по умолчанию:
- profiles/create_profile.html
- profiles/edit_profile.html
- profiles/profile_detail.html
- profiles/profile_list.html
За что они отвечают, понятно из их имен.
Написание шаблонов для отображения профайла юзера (profile_detail.html) и списка профайлов (profile_list.html) оставим в качестве упражнения для заинтересованных читателей этого поста.
А вот шаблоны создания и редактирования своего профайла юзером сделаем. Для простоты и краткости сделаем их одинаковыми.
В каталоге, указанном в параметре TEMPLATE_DIRS файла settings.py, создаем подкаталог profiles, а в нем шаблоны edit_profile.html и create_profile.html с таким вот (например) содержанием:
{% extends "base.html" %}
{% block content %}
<form action="" method="post"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
{% endblock %}
Предполагается, что шаблон base.html с основным html-кодом страниц сайта у вас есть.
Лирическое отступление. Я использую для регистрации юзеров еще одно приложение того же автора - registration. Профайл юзера создается автоматически по сигналу от этого приложения при активации нового юзера на сайте. Так что, лично мне шаблон создания нового профайла вообще не нужен.
Готово! Логинимся каким-нибудь юзером на свой сайт, переходим в браузере по адресу mysite.ru/profiles/edit/ упс... На станице редактирования профайла только одно поле about из нашей расширенной модели. Имя и фамилию, которые хранятся во встроенной модели, нужно редактировать в админке. Хорошо бы сделать так, чтобы юзер на одной странице мог редактировать имя, фамилию и заметку о себе.
Использованное нами приложение profiles автоматически создает форму редактирования профайла на основе модели, указанной в параметре AUTH_PROFILE_MODULE файла settings.py. А в этой модели у нас единственное поле about (служебное связывающее поле user отбрасывается). Но это приложение позволяет передавать своим функциям-представлениям доп.параметы, среди которых есть параметр
form_class, задающий класс формы, используемый для редактирования профайла. Этой фичей и воспользуемся.
Чтобы не изменять элементы внешнего приложения, добавми в urls.py своего проекта строчку перед инклудом урл приложения profiles. Эта строчка перехватит обращение при запросе на редактирование профайла и вместо вызова представления, предоставляемого profiles по умолчанию, вызовет представление с нужным доп.параметром. Соответствующий фрагмент urls.py проекта должен выглядеть как-то так:
urlpatterns = patterns('',
...
(r'^profiles/edit/$', 'profiles.views.edit_profile', {'form_class': forms.ProfileForm}, 'profiles_create_profile'),
(r'^profiles/', include('profiles.urls')),
...
)
Теперь нужно добавить определение класса формы ProfileForm в файл forms.py проекта. Идея заключается в том, что мы
- сабклассим форму редактирования профайла на основе модели,
- добавляем два поля для имени и фамилии юзера,
- при создании экземпляра формы запоминаем экземпляр модели профайла, передаваемый в параметре instance,
- считываем из обьекта профайла связанный обьект user и инициализируем значениями first_name/last_name два поля нашей формы,
- при сохранении модели (метод save) присваиваем значения этих полей соотв.полям обьекта user и сохраняем его вместе с нашим профайлом.
Код:
import django
class ProfileForm(django.forms.ModelForm):
first_name = django.forms.CharField(max_length=30, required=False)
last_name = django.forms.CharField(max_length=30, required=False)
def __init__(self, *args, **kwargs):
# получаем обьект профайла
self.prof = kwargs.get('instance', None)
initial = {'first_name': self.prof.user.first_name, 'last_name': self.prof.user.last_name}
# в два поля нашей формы помещаем значения соотв.полей из модели user
kwargs['initial'] = initial
super(ProfileForm, self).__init__( *args, **kwargs)
class Meta:
# форма для нашей модели профайла
model = models.UserProfile
# для красоты, чтобы поля в форме шли в правильном порядке
fields = ('first_name', 'last_name', 'about')
def save(self, commit=True):
super(ProfileForm, self).save(commit)
if commit:
self.prof.user.first_name = self.cleaned_data['first_name']
self.prof.user.last_name = self.cleaned_data['last_name']
self.prof.user.save()
Теперь при редактировании своего профайла по адресу mysite.ru/profiles/edit/ залогиненный юзер на одной страничке может редактировать свои имя, фамилию, и заметку 'о себе'.
При этом имя/фамилия сохраняются во встроенной модели django.contrib.auth.models.User в полях first_name/last_name, а заметка 'о себе', в поле about нашей модели UserProfile.
PS. По ходу пьесы нашел онлайн-сервис экранирования html-кода в текст для вставки в блог. Может кому пригодится.
Комментариев нет:
Отправить комментарий