Избитая задача: сделать профайл пользователя, расширяющий встроенную модель . Допустим, нужно добавить в профайл юзера поле about , где он может написать кратко о своих интересах и т.п. Предполагается, что система авторизации юзеров на основе встроенных стредств Django у вас на сайте уже имеется.

Делаем, как прописано в мануалах 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 с таким вот (например) содержанием (код кривой отображается, видно из-за экранирования html, как правильно html сюда вводить - непонятно):

{% extends "base.html" %} {% block content %} {% csrf_token %} {{ form.as_p }} /> {% 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 .