2015-07-28 2 views
1

Django: When extending User, better to use OneToOneField(User) or ForeignKey(User, unique=True)?разница между ForeignKey и простирающейся пользовательского класса/модели в Django

Я прошел через эту тему и обнаружил, что ForeignKey (с unique=True) лучше, чем OneToOneField, но что о расширении самого класса, т.е. вот пример

class UserProfile(models.Model): 
    user = models.ForeignKey(User, unique=True) 
    # some additional fields 

ИЛИ

class UserProfile(User): 
    # some additional fields 

Разница между этими двумя подходами и плюсы/минусы и которые один я должен использовать?

EDIT: я могу использовать AbstractUser а

from django.contrib.auth.models import AbstractUser 
class User(AbstractUser): 
    phone_no = models.CharField(max_length=10, blank=True) 

, а затем упомянул AUTH_USER_MODEL = 'myapp.User' в settings.py

основной проблемой является то, что подход, который я должен использовать, расширив класс или ForeignKey?

Дубликаты:

What's the difference between OneToOne and Subclassing a model in Django

Django Model Inheritance versus OneToOne field

MORE EDIT

Забудьте о ForeginKey или OneToOne, предположим, только один из этих двух существует, теперь сравните это с простирающейся/подклассов подход

+1

Поскольку вы знаете, что один-на-один лучше, чем использование ForeignKey, почему * * вы используете ForeignKey в своем примере? –

+0

мой плохой, отредактировал вопрос –

+0

После вашего редактирования, как вы поддерживаете, что «a ForeignKey' лучше, чем« OneToOneField »? – Wtower

ответ

0

Там i s не лучший способ сделать, дело в том, что если вы делаете расширение AbstractUser, вам нужно переопределить некоторые функции, чтобы он был длиннее, но у вас больше контроля над тем, что вы хотите сделать с вашим пользователем.

Сделать поле OneToOne на пользователя Джанго по умолчанию быстрее, а также позволяет добавлять собственные пользовательские пользовательские поля, но вы можете использовать непосредственно пользователя поля по умолчанию в пользовательском объекте, и ваше пользовательское поле на пользователя:

from django.contrib.auth.models import User 

class Employee(models.Model): 
    user = models.OneToOneField(User) 
    department = models.CharField(max_length=100) 

вы можете сделать:

>>> u = User.objects.get(username='fsmith') 
>>> freds_department = u.employee.department 

Так что это действительно зависит от того, что вы хотите сделать. Вы можете сделать свой Пользователь, например, если вы хотите, чтобы почтовый адрес был как идентификационный токен (это обычный пример, но вы можете делать гораздо больше вещей: p).

Here - хорошее объяснение (я размещаю его на пользователе, но вы можете прочитать всю страницу, это очень интересно, когда вы погружаетесь в пользователя и аутентификацию в Django).

Надеюсь, что это поможет.

+0

Я отредактировал свой вопрос, пожалуйста, прочитайте его, пожалуйста, измените ваш ответ соответствующим образом. –

+0

Это абсолютно то, что я сделал :) и ссылку, которую я вам дал, говорят только о том, почему OneToOne или зачем расширять модель BaseUser. Я не вижу, где я говорю о внешнем ключе в своем ответе. Сначала я говорю о расширении, а затем OneToOne и, наконец, расскажу вам, почему вы должны выбрать тот или иной (и ссылка довольно полная). Независимо от того, я отредактировал свой ответ, яснее. Надеюсь, это ясно – Bestasttung

+0

все еще не то, что вы хотите @johnsnow? – Bestasttung

0

Я скептически отношусь к преимуществам уникальных стихов FK один к одному, вы могли бы достичь аналогичной вещи в админе, используя fieldsets, поэтому я предпочел бы иметь явное поле «один-к-одному» на модели , что делает природу отношения более очевидной.

Дублированные вопросы, к которым вы привязаны, не относятся к модели auth User и обсуждают индивидуальное соответствие модели с натурами.Технически они одинаковы (например, наследование модели использует поле «один-к-одному»)

Таким образом, в конечном итоге выбор сводится к семантике: ваша родственная модель является «подклассом» другого или просто ссылкой для дальнейшего связанная информация?

В случае auth User вы спросите себя: есть ли дополнительные поля, которые должны присутствовать для всех пользователей (например, пол, facebook id и т. Д.)? или некоторые поля, которые вы хотите опустить из модели Django User (например, для использования уникального адреса электронной почты в качестве имени пользователя)?

В этом случае очевидным выбором является расширение AbstractUser. Если вы не можете представить, указав null=True на свою модель профиля пользователя, вы должны рассмотреть возможность расширения AbstractUser.

С другой стороны, может быть какие-то данные, которые более аналогична старой UserProfile модели (посмотрите, как все было в старых версиях Django до предоставления AbstractUser поддержали: https://docs.djangoproject.com/en/1.4/topics/auth/#storing-additional-information-about-users)

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

1

Во-первых, хорошо знать, что в настоящее время существует несколько вариантов расширения пользовательской модели Django. Каждый из них имеет свою цель (но есть и некоторые перекрытия). Документация Django немного запутанна, поскольку, как представляется, из this существует два варианта: т. Е. Прокси или OneToOneField. Однако это относится к модели пользователя , так как в документах обрабатываются пользовательских моделей.

Так на практике существует четыре (общие) способы борьбы с расширением модели пользователя:

  1. Proxy модель (нет новых databasefields, просто изменить модель поведения пользователя, то есть новый порядок, новые методы , и т.д.).
  2. OneToOneField (дополнительные поля данных, необходимые в пределах существующей модели пользователя Djang).
  3. Пользовательские модели пользователя с AbstractBaseUser (дополнительных полями данных необходимо, а также конкретными требованиями в отношении процесса authenticaton, например, с использованием EMAILADDRESS ALS идентификатора маркеров вместо имени пользователя).
  4. Пользовательская модель пользователя с AbstractUser (необходимы дополнительные поля данных, изменение на проверку подлинности).

Реализация вариантов 3 и 4 необходима новая миграция базы данных, поэтому они подходят только для новых проектов.

This is a good link for more detail on this. Я думаю, что варианты 2 и 4 ближе всего, так как оба хотят расширить, чтобы добавить больше полей данных. Писатель, похоже, выступает за вариант 2, но при запуске нового варианта проекта 4 мне становится легче. Где-то в комментариях автор упоминает о риске того, что вы не сможете перейти на новые версии Django для вариантов 3 и 4. Мне кажется надуманным, но я не могу сказать на самом деле.

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