2016-10-20 4 views
1

Я знаю, что этот вопрос задан сотни раз, но большинство из них содержат -принятые ответы, которые больше не действительны. Некоторые из них предназначены для Django 1.5, некоторые из них даже старше.Django 1.8+ расширяет модель пользователя

Итак, я ищу актуальный ответ. Вопрос, который больше всего напоминает мою проблему, - this one.

Я использую модуль django-registration, и я хочу, чтобы у пользователей были дополнительные поля (например, целое число user.points). Я в порядке с реализацией моей собственной модели MyUser и изменением остальной части моей программы соответственно. Однако я сомневаюсь, что это будет работать в соответствии с модулем регистрации. Поэтому я думаю, что идеальным способом было бы использовать модель User и каким-то образом связать их так, чтобы всякий раз, когда создается объект User, создается соответствующий объект MyUser со значениями по умолчанию для дополнительных полей.

-Как, я могу это сделать с Django 1.8+?

Спасибо за любую помощь,

+0

Это не изменяется между Django 1.5 и 1.8, связанных между собой ответ не является устаревшим. – GwynBleidD

ответ

1

Статья о теме: How to Extend Django User Model

Что я использую является One-To-One подход:

class UserProfile(models.Model): 
    user = models.OneToOneField(User, related_name="profile") 
    #more fields 

    @staticmethod 
    @receiver(post_save, sender=User, dispatch_uid="at_user_post_save") 
    def user_post_save(sender, instance, **kwargs): 
     #create new profile on user.save() (if necessary) 
     profile, new = UserProfile.objects.get_or_create(user=instance) 


#in view 
profile = request.user.profile 

UPDATE:

ли есть ли какие-либо другие оговорки? Как то, что происходит, когда я удаляю UserProfile ?

UserProfile это тот, кто имеет отношение, так при удалении не user должны быть удалены. Вы можете управлять тем, что должно быть поведением, когда user удаляется через on_delete kwarg.

Также у них всегда есть те же секретные ключи?

Нет у каждого класса есть свои собственные первичные ключи, только UserProfile держит ПК в своей user.

OneToOneField в концептуально ForeignKey с unique=True, большая разница в том, что обратная сторона отношения не возвращают список с 0/1 элементов, а сам элемент или поднять DoesNotExist или None если null=True.

Единственное, что мне не нравится в этом подходе, это то, что вам всегда нужно сделать еще 1 запрос, чтобы получить user.profile. Я все еще не могу найти хороший и чистый подход к всегда .select_related('profile'), когда новый user извлекается из auth, но это скорее проблема системы аутентификации, а не самого подхода.

+0

Этот метод кажется более подходящим сейчас :) Любые возражения? – jeff

+0

Я иду с таким подходом. Он создает «UserProfile», поскольку создается «Пользователь». Мне просто нужно получить пользователя как 'request.user.profile' в представлениях, но есть ли какие-либо другие оговорки? Как то, что происходит, когда я удаляю «UserProfile»? Соответствует ли также и «Пользователь»? Также у них всегда есть те же личные ключи? – jeff

+0

@halilpazarlama обновил вопрос с некоторыми ответами на ваши вопросы. Я также разместил ссылку на статью, объясняющую разные подходы со своими плюсами и минусами. – Todor

1

django-registration поддерживает пользовательские модели пользователей, поэтому создать собственную модель пользователя и использовать ее с django-registration не составит труда.

Все, что вам нужно сделать, это создать регистрационную форму на основе registration.forms.RegistrationForm, а затем использовать ее в RegistrationView. Вам также необходимо оставить email и is_active полями по умолчанию модели пользователя django и предоставить метод email_user в пользовательской модели. USERNAME_FIELD также должны быть указаны. Другие требования зависят от вашего метода проверки подлинности.

Подробнее об этом можно узнать в django-registration docs.

1

Первый вопрос для расширения пользовательской модели: вы должны начать с чистого проекта django, который вы еще не вызывали: «python manage.py migrate».

Это связано с тем, что если вы сделали, перенесенный в прошлом, модель без продолжения уже создана, django не знает, как ее изменить.

Теперь, чтобы выбрать другую модель пользователя, первое, что вы должны сделать, это на вашем settings.py:

AUTH_USER_MODEL = 'APPNAME.Account' 

Рекомендуется создать новое приложение для обработки пользовательской модели. имейте в виду не называть «учетную запись» приложения, поскольку он сталкивается с уже существующей моделью пользователя.

Я создал приложение, называемое accountb. на моделях:

from django.db import models 
from django.contrib.auth.models import UserManager 
from django.contrib.auth.models import AbstractUser 

class AccountManager(UserManager): 
    def create_user(self, email, password=None, **kwargs): 
     if not email: 
      raise ValueError('Users must have a valid email address.') 
     if not kwargs.get('username'): 
      raise ValueError('Users must have a valid username.') 

     account = self.model(
      email=self.normalize_email(email), 
      username=kwargs.get('username'), 
      year_of_birth = kwargs.get('year_of_birth'), 
      #MODEL = kwargs.get('MODEL_NAME'), 
     ) 
     account.set_password(password) 
     account.save() 

     return account 

    def create_superuser(self, email, password, **kwargs): 
     account = self.create_user(email, password, **kwargs) 
     account.is_staff = True 
     account.is_superuser = True 
     account.save() 

     return account 

class Account(AbstractUser): 
    email = models.EmailField(unique=True) 
    #ADD YOUR MODELS HERE 

    objects = AccountManager() 

    def __str__(self): 
     return self.email 

Кроме того, не забудьте зарегистрировать его на admin.py:

from django.contrib import admin 
from .models import Account 

admin.site.register(Account) 
+0

Большое вам спасибо! Кажется, это работает нормально, но я просто запутался в последней части (зарегистрировав ее на 'admin.py'), если я сделаю это так, как вы предлагали, я не вижу новых полей. Когда я регистрирую его просто с помощью 'admin.site.register (Account)', теперь я вижу новые поля. Интересно, почему это происходит. Я все равно соглашусь с вашим ответом, но я также хотел бы поблагодарить вас за сотрудничество. Еще раз спасибо всем ответчикам! – jeff

+0

Теперь модуль регистрации дает мне ошибку. Если вас это интересует, вот мое продолжение [вопрос] (http://stackoverflow.com/questions/40155777/custom-user-models-in-django-no-such-table-auth-user) :) – jeff

+1

My Плохо, что последней частью был какой-то несвязанный код. Я отредактировал свой ответ. – idik

Смежные вопросы