문제

사용자 정의 필드를 사용하여 사용자 모델(Django의 인증 앱과 함께 번들로 제공)을 확장하는 가장 좋은 방법은 무엇입니까?또한 (인증 목적으로) 이메일을 사용자 이름으로 사용하고 싶습니다.

나는 이미 본 적이 있어요 약간의 방법 하지만 어느 것이 가장 좋은지 결정할 수는 없습니다.

도움이 되었습니까?

해결책

가장 덜 고통스럽고 Django가 권장하는 방법은 다음과 같습니다. OneToOneField(User) 재산.

기존 User 모델 확장

관련된 정보를 저장하고 싶다면 User, 당신은 일대일 관계 추가 정보를 위한 필드가 포함된 모델에.이 일대일 모델은 사이트 사용자에 대한 비인증 관련 정보를 저장할 수 있으므로 프로필 모델이라고도 합니다.

연장한다고 하더군요 django.contrib.auth.models.User 그것을 대체하는 것도 효과가 있습니다 ...

커스텀 User 모델 대체

일부 종류의 프로젝트에는 Django에 내장된 인증 요구 사항이 있을 수 있습니다. User 모델이 항상 적절한 것은 아닙니다.예를 들어 일부 사이트에서는 사용자 이름 대신 이메일 주소를 식별 토큰으로 사용하는 것이 더 합리적입니다.

[에드: 두 가지 경고와 알림이 따릅니다., 이것이라고 언급 꽤 과감한.]

나는 Django 소스 트리에서 실제 User 클래스를 변경하거나 인증 모듈을 복사 및 변경하는 일을 확실히 피하겠습니다.

다른 팁

메모:이 답변은 더 이상 사용되지 않습니다.Django 1.7 이상을 사용하는 경우 다른 답변을 참조하세요.

이것이 내가 하는 방법이다.

#in models.py
from django.contrib.auth.models import User
from django.db.models.signals import post_save

class UserProfile(models.Model):  
    user = models.OneToOneField(User)  
    #other fields here

    def __str__(self):  
          return "%s's profile" % self.user  

def create_user_profile(sender, instance, created, **kwargs):  
    if created:  
       profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User) 

#in settings.py
AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile'

사용자가 생성되면 사용자가 저장될 때마다 사용자 프로필이 생성됩니다.그런 다음 사용할 수 있습니다

  user.get_profile().whatever

다음은 문서의 추가 정보입니다.

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

업데이트: 점에 유의하시기 바랍니다 AUTH_PROFILE_MODULE v1.5부터 더 이상 사용되지 않습니다. https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module

글쎄요, 2008년 이후 어느 정도 시간이 흘렀고 이제는 새로운 대답이 필요한 때입니다.Django 1.5부터 사용자 정의 User 클래스를 만들 수 있습니다.사실 제가 이 글을 쓰고 있는 시점에는 이미 master로 merge되어 있으니 한번 사용해보시면 됩니다.

거기에 대한 정보가 있어요 문서 또는 더 자세히 알아보고 싶다면 이 커밋.

당신이해야 할 일은 추가하는 것뿐입니다. AUTH_USER_MODEL 다음 중 하나를 확장하는 사용자 정의 사용자 클래스에 대한 경로가 있는 설정으로 AbstractBaseUser (더 사용자 정의 가능한 버전) 또는 AbstractUser (확장할 수 있는 다소 오래된 User 클래스)

클릭하기 귀찮은 분들을 위해 다음 코드 예제를 참조하세요(출처: 문서):

from django.db import models
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)


class MyUserManager(BaseUserManager):
    def create_user(self, email, date_of_birth, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=MyUserManager.normalize_email(email),
            date_of_birth=date_of_birth,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, date_of_birth, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        u = self.create_user(username,
                        password=password,
                        date_of_birth=date_of_birth
                    )
        u.is_admin = True
        u.save(using=self._db)
        return u


class MyUser(AbstractBaseUser):
    email = models.EmailField(
                        verbose_name='email address',
                        max_length=255,
                        unique=True,
                    )
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['date_of_birth']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __unicode__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

Django 1.5부터 사용자 모델을 쉽게 확장하고 데이터베이스에 단일 테이블을 유지할 수 있습니다.

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _

class UserProfile(AbstractUser):
    age = models.PositiveIntegerField(_("age"))

또한 설정 파일에서 현재 사용자 클래스로 구성해야 합니다.

# supposing you put it in apps/profiles/models.py
AUTH_USER_MODEL = "profiles.UserProfile"

많은 사용자 기본 설정을 추가하려면 OneToOneField 옵션이 더 나은 선택일 수 있습니다.

타사 라이브러리를 개발하는 사람들을 위한 참고 사항:사용자 클래스에 접근해야 한다면 사람들이 변경할 수 있다는 점을 기억하세요.공식 도우미를 활용해 올바른 수업을 받으세요

from django.contrib.auth import get_user_model

User = get_user_model()

공식적인 권고사항이 있습니다. 사용자에 대한 추가 정보 저장.Django Book에서도 이 문제를 섹션에서 논의합니다. 프로필.

아래는 사용자를 확장하는 또 다른 접근 방식입니다.나는 두 가지 접근 방식보다 더 명확하고 쉽고 읽기 쉽다고 생각합니다.

http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/

위의 접근 방식을 사용하면 다음과 같습니다.

  1. 당신은 사용할 필요가 없습니다user.get_profile().new속성 사용자와 관련된 추가 정보에 액세스합니다
  2. 추가로 새로운 속성에 직접 액세스 할 수 있습니다user.new속성

django 게시물 저장 신호를 사용하여 사용자가 생성될 때마다 새 항목을 생성하여 사용자 프로필을 간단히 확장할 수 있습니다.

models.py

from django.db.models.signals import *
from __future__ import unicode_literals

class userProfile(models.Model):

    userName = models.OneToOneField(User, related_name='profile')
    city = models.CharField(max_length=100, null=True)

    def __unicode__(self):  # __str__
        return unicode(self.userName)

def create_user_profile(sender, instance, created, **kwargs):
    if created:
    userProfile.objects.create(userName=instance)

post_save.connect(create_user_profile, sender=User)

새 사용자가 생성되면 직원 인스턴스가 자동으로 생성됩니다.

사용자 모델을 확장하고 사용자를 생성하는 동안 추가 정보를 추가하려면 django-betterforms(http://django-betterforms.readthedocs.io/en/latest/multiform.html).userProfile 모델에 정의된 모든 필드가 포함된 사용자 추가 양식이 생성됩니다.

models.py

from django.db.models.signals import *
from __future__ import unicode_literals

class userProfile(models.Model):

    userName = models.OneToOneField(User)
    city = models.CharField(max_length=100)

    def __unicode__(self):  # __str__
        return unicode(self.userName)

Forms.py

from django import forms
from django.forms import ModelForm
from betterforms.multiform import MultiModelForm
from django.contrib.auth.forms import UserCreationForm
from .models import *

class profileForm(ModelForm):

    class Meta:
        model = Employee
        exclude = ('userName',)


class addUserMultiForm(MultiModelForm):
    form_classes = {
        'user':UserCreationForm,
        'profile':profileForm,
    }

views.py

from django.shortcuts import redirect
from .models import *
from .forms import *
from django.views.generic import CreateView

class addUser(CreateView):
    form_class = addUserMultiForm
    template_name = "addUser.html"
    success_url = '/your url after user created'

    def form_valid(self, form):
        user = form['user'].save()
        profile = form['profile'].save(commit=False)
        profile.userName = User.objects.get(username= user.username)
        profile.save()
        return redirect(self.success_url)

addUser.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="." method="post">
            {% csrf_token %}
            {{ form }}     
            <button type="submit">Add</button>
        </form>
     </body>
</html>

urls.py

from django.conf.urls import url, include
from appName.views import *
urlpatterns = [
        url(r'^add-user/$', addUser.as_view(), name='addDistributor'),
]

전문가처럼 Django 사용자 모델(UserProfile) 확장하기

나는 이것이 매우 유용하다는 것을 알았습니다. 링크

추출물:

django.contrib.auth.models에서 사용자 가져오기

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

Django 1.5의 새로운 기능으로 이제 자신만의 Custom User Model을 만들 수 있습니다(위의 경우에는 좋은 방법인 것 같습니다).인용하다 'Django에서 인증 사용자 정의'

아마도 1.5 릴리스의 가장 멋진 새로운 기능일 것입니다.

이것이 제가 하는 일이며 제 생각에는 이것이 가장 간단한 방법입니다.새로운 사용자 정의 모델에 대한 객체 관리자를 정의한 다음 모델을 정의하십시오.

from django.db import models
from django.contrib.auth.models import PermissionsMixin, AbstractBaseUser, BaseUserManager

class User_manager(BaseUserManager):
    def create_user(self, username, email, gender, nickname, password):
        email = self.normalize_email(email)
        user = self.model(username=username, email=email, gender=gender, nickname=nickname)
        user.set_password(password)
        user.save(using=self.db)
        return user

    def create_superuser(self, username, email, gender, password, nickname=None):
        user = self.create_user(username=username, email=email, gender=gender, nickname=nickname, password=password)
        user.is_superuser = True
        user.is_staff = True
        user.save()
        return user



  class User(PermissionsMixin, AbstractBaseUser):
    username = models.CharField(max_length=32, unique=True, )
    email = models.EmailField(max_length=32)
    gender_choices = [("M", "Male"), ("F", "Female"), ("O", "Others")]
    gender = models.CharField(choices=gender_choices, default="M", max_length=1)
    nickname = models.CharField(max_length=32, blank=True, null=True)

    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    REQUIRED_FIELDS = ["email", "gender"]
    USERNAME_FIELD = "username"
    objects = User_manager()

    def __str__(self):
        return self.username

이 코드 줄을 추가하는 것을 잊지 마세요. settings.py:

AUTH_USER_MODEL = 'YourApp.User'

이것이 내가 하는 일이고 항상 효과가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top