Сохранить внешний ключ между моделью профиля и моделью пользователя

Первые шаги в django's (1.5) функциях аутентификации и до сих пор у меня было много проблем, просто пытаясь вставить адрес электронной почты пользователя (который является полем имени пользователя в пользовательской модели) как ForeignKey в модели профиля Specialist.

Два вопроса:

  1. Является ли это наилучшей практикой для внешнего ключа к данным текущих пользователей в модели профиля? Обратите внимание: я не пытаюсь сохранить нового пользователя, просто связываю данные его профиля с объектом аутентифицированного пользователя (CustomUser). К тому времени, когда пользователь достигает представления ниже, он уже аутентифицирован.
  2. Какие изменения необходимы для того, чтобы это работало должным образом?

Обратите внимание: прежде чем зайти так далеко, я столкнулся с несколькими ошибками user_id не может быть нулевым или должно быть в экземпляре объекта CustomUser. Теперь я вижу, что ничего не сохраняется в база данных после того, как меня перенаправили на /profile/.

# view

@login_required
def profile_setup_specialist(request):
    if request.method == 'POST':
        current_user = CustomUser.objects.get(email = request.user.email)
        posted_form = SpecialistCreationForm(request.POST, instance=current_user)
        if posted_form.is_valid():
            profile = posted_form.save(commit=False)
            profile.user = current_user
            profile.save()
            return HttpResponseRedirect('/profile/')

            # ..


# profile model

class Specialist(models.Model):

    user = models.ForeignKey(CustomUser, related_name='Specialist')
    foo = models.CharField(max_length=100)
    # ...

    def __unicode__(self):
        return self.foo

 # form

class SpecialistCreationForm(forms.ModelForm):

    class Meta:
        model = Specialist
        exclude = ['user']


# custom user model

class CustomUser(AbstractBaseUser, PermissionsMixin):

    email           = models.EmailField(
                        verbose_name='email address',
                        max_length=255,
                        unique=True,
                        db_index=True,
                        )

    # ..

    objects = CustomUserManager()

    USERNAME_FIELD  = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name', 'state']

    def __unicode__(self):
        return self.email

person user3230295    schedule 24.01.2014    source источник


Ответы (2)


Я знаю, что написание пользовательских пользовательских моделей - это не весело, что включает в себя написание/расширение множества пользовательских форм, таких как этот вопрос. Если бы я придерживался модели обычного пользователя, я бы сказал, что модель специалиста имеет отношения OneToOne с пользователем,

Класс Специалист(модели.Модель):

user = models.OneToOneField(User)

так что вы можете запросить профиль, как это request.user.specialist

person James Lin    schedule 24.01.2014
comment
Спасибо, но пользовательская модель пользователя на самом деле работает нормально, и я могу успешно получить адрес электронной почты пользователя с помощью request.user.email, это связь с пользовательской моделью через FK, которая меня сбивает с толку. - person user3230295; 24.01.2014

Решение этих проблем было найдено путем копания в базе данных SQLite, как было предложено здесь.

Команда manage.py sqlall показала ниже, где скрытое поле id модели, которое автоматически создает Django, указано как PRIMARY KEY.

BEGIN;
CREATE TABLE "profiles_specialist" (
    "id" integer NOT NULL PRIMARY KEY,
    "user_id" integer NOT NULL REFERENCES "auth2_customuser" ("id"),

Скрытое поле id каким-то образом потеряло свой статус PK и было установлено только как INTEGER, которое не могло автоматически увеличиваться каждый раз при сохранении нового объекта.

Это поле нужно было сбросить на INTEGER PRIMARY KEY, и тогда все работало отлично.

person user3230295    schedule 26.01.2014