사용자 정의 필드로 사용자 모델 (Django의 인증 앱과 함께 제공)을 확장하는 가장 좋은 방법은 무엇입니까? 이메일을 사용자 이름으로 사용하고 싶습니다 (인증 목적으로).
사용자 정의 필드로 사용자 모델 (Django의 인증 앱과 함께 제공)을 확장하는 가장 좋은 방법은 무엇입니까? 이메일을 사용자 이름으로 사용하고 싶습니다 (인증 목적으로).
답변:
가장 고통스럽고 실제로 장고가 권장하는 방법은 OneToOneField(User)
속성을 통하는 것 입니다.
기존 사용자 모델 확장
…
와 관련된 정보를 저장하려는 경우 추가 정보를위한 필드가 포함 된 모델에 일대일 관계 를
User
사용할 수 있습니다 . 이 일대일 모델을 사이트 모델에 대한 인증되지 않은 관련 정보를 저장할 수 있으므로 종종 프로필 모델이라고합니다.
즉, django.contrib.auth.models.User
그것을 확장 하고 대체하는 것도 효과가 있습니다 ...
사용자 정의 사용자 모델 대체
일부 종류의 프로젝트에는 Django의 내장
User
모델이 항상 적합하지 않은 인증 요구 사항이있을 수 있습니다 . 예를 들어, 일부 사이트에서는 사용자 이름 대신 전자 메일 주소를 식별 토큰으로 사용하는 것이 더 합리적입니다.[Ed : 두 가지 경고와 알림 이 이어지는데, 이는 상당히 과감한 것 입니다.]
Django 소스 트리에서 실제 사용자 클래스를 변경하거나 인증 모듈을 복사 및 변경하지 마십시오.
user = models.ForeignKey(User, unique=True)
이것과 동일 user = models.OneToOneField(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
1.5 버전부터 사용되지 않습니다 : https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module
user = models.ForeignKey( User )
하여 프로파일 객체를 검색 해야합니다 user.get_profile()
. 기억하십시오 from django.contrib.admin.models import User
.
User
글쎄요, 2008 년 이후 어느 정도 시간이 지났고 이제는 새로운 답변을 얻을 시간입니다. Django 1.5부터 사용자 정의 사용자 클래스를 만들 수 있습니다. 실제로, 나는 이것을 쓸 때 이미 마스터로 병합되어 있으므로 시도해 볼 수 있습니다.
그것에 대한 몇 가지 정보가 있습니다 이 커밋 문서 있거나 더 깊이 파고 싶다면 여기에 커밋하십시오 .
당신이해야 할 추가 AUTH_USER_MODEL
사용자 정의 사용자 클래스에 대한 경로를 사용하여 설정에 하기 만하면됩니다 AbstractBaseUser
(사용자 정의 가능 버전) 또는 AbstractUser
확장 할 수있는 더 오래되거나 덜 사용되는 사용자 클래스).
클릭하기 게으른 사람들을 위해 다음 코드 예제 ( docs 에서 가져온 ) :
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
email
사용자 이름 이므로
unique=True
하려면 이메일 필드 에 추가해야 USERNAME_FIELD
합니다
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_social_auth
OneToOne 관계를 사용하는 것이 좋습니다. 이 방법을 사용하지 마십시오. 그렇지 않으면 마이그레이션이 엉망이됩니다.
django_social_auth
플러그인을 결합 하고 AUTH_USER_MODEL을 소셜 인증 사용자에게 정의 하려고 시도한 것 같습니다 . 그런 다음 manage.py 마이그레이션을 실행하면 앱이 엉망이되었습니다. 대신 소셜 인증 사용자 모델을 여기에 설명 된 OneToOne 관계로 사용했습니다. stackoverflow.com/q/10638293/977116
Changing this setting after you have tables created is not supported by makemigrations and will result in you having to manually write a set of migrations to fix your schema
소스 와 관련이있을 것입니다 : docs.djangoproject.com/en/dev/topics/auth/customizing/…
사용자에 대한 추가 정보 저장 에 대한 공식 권장 사항이 있습니다 . Django Book은이 문제에 대해서도 프로파일 섹션에서 설명합니다 .
아래는 사용자를 확장하는 또 다른 방법입니다. 두 가지 접근 방식보다 더 명확하고 쉽고 읽기 쉽다고 생각합니다.
http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
위의 접근 방식을 사용하십시오.
Django post save 신호를 사용하여 사용자를 만들 때마다 새 항목을 만들어 사용자 프로필을 간단하게 확장 할 수 있습니다
from django.db.models.signals import *
from __future__ import unicode_literals
class UserProfile(models.Model):
user_name = models.OneToOneField(User, related_name='profile')
city = models.CharField(max_length=100, null=True)
def __unicode__(self): # __str__
return unicode(self.user_name)
def create_user_profile(sender, instance, created, **kwargs):
if created:
userProfile.objects.create(user_name=instance)
post_save.connect(create_user_profile, sender=User)
새 사용자가 생성되면 직원 인스턴스가 자동으로 생성됩니다.
사용자 모델을 확장하고 사용자를 작성하는 동안 추가 정보를 추가하려는 경우 django-betterforms ( http://django-betterforms.readthedocs.io/en/latest/multiform.html )를 사용할 수 있습니다 . UserProfile 모델에 정의 된 모든 필드가있는 사용자 추가 양식이 작성됩니다.
from django.db.models.signals import *
from __future__ import unicode_literals
class UserProfile(models.Model):
user_name = models.OneToOneField(User)
city = models.CharField(max_length=100)
def __unicode__(self): # __str__
return unicode(self.user_name)
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 = ('user_name',)
class addUserMultiForm(MultiModelForm):
form_classes = {
'user':UserCreationForm,
'profile':ProfileForm,
}
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 = "add-user.html"
success_url = '/your-url-after-user-created'
def form_valid(self, form):
user = form['user'].save()
profile = form['profile'].save(commit=False)
profile.user_name = User.objects.get(username= user.username)
profile.save()
return redirect(self.success_url)
<!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>
from django.conf.urls import url, include
from appName.views import *
urlpatterns = [
url(r'^add-user/$', AddUser.as_view(), name='add-user'),
]
프로처럼 장고 사용자 모델 (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의 새로운 기능으로, 이제 자신 만의 사용자 정의 사용자 모델을 만들 수 있습니다 (위의 경우에 좋은 것으로 보입니다). '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'
이것이 내가하는 일이며 항상 작동합니다.
현재 Django 2.2부터 새 프로젝트를 시작할 때 권장되는 방법은 AbstractUser에서 상속 된 사용자 지정 사용자 모델을 만든 다음 AUTH_USER_MODEL을 모델로 지정하는 것입니다.