Форум для программистов - задавайте интересные вопросы - получайте квалифицированные ответы
Расширенный профайл юзера в Django
  • seocoderseocoder April 2011
    Избитая задача: сделать профайл пользователя, расширяющий встроенную модель django.contrib.auth.models.User. Допустим, нужно добавить в профайл юзера поле 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.

    взято с http://habrahabr.ru/sandbox/28188/
Webparadox - разработка мобильных приложений под iOS и Android.