[django] Django에서 사용자 정의 필드로 사용자 모델 확장
사용자 정의 필드로 사용자 모델 (Django의 인증 앱과 함께 제공)을 확장하는 가장 좋은 방법은 무엇입니까? 이메일을 사용자 이름으로 사용하고 싶습니다 (인증 목적으로).
답변
가장 고통스럽고 실제로 장고가 권장하는 방법은 OneToOneField(User)
속성을 통하는 것 입니다.
기존 사용자 모델 확장
…
와 관련된 정보를 저장하려는 경우 추가 정보를위한 필드가 포함 된 모델에 일대일 관계 를
User
사용할 수 있습니다 . 이 일대일 모델을 사이트 모델에 대한 인증되지 않은 관련 정보를 저장할 수 있으므로 종종 프로필 모델이라고합니다.
즉, django.contrib.auth.models.User
그것을 확장 하고 대체하는 것도 효과가 있습니다 …
사용자 정의 사용자 모델 대체
일부 종류의 프로젝트에는 Django의 내장
User
모델이 항상 적합하지 않은 인증 요구 사항이있을 수 있습니다 . 예를 들어, 일부 사이트에서는 사용자 이름 대신 전자 메일 주소를 식별 토큰으로 사용하는 것이 더 합리적입니다.[Ed : 두 가지 경고와 알림 이 이어지는데, 이는 상당히 과감한 것 입니다.]
Django 소스 트리에서 실제 사용자 클래스를 변경하거나 인증 모듈을 복사 및 변경하지 마십시오.
답변
참고 :이 답변은 더 이상 사용되지 않습니다. 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
답변
글쎄요, 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
답변
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/
위의 접근 방식을 사용하십시오.
- 사용자와 관련된 추가 정보에 액세스 하기 위해 user.get_profile (). newattribute 를 사용할 필요는 없습니다
. - user.newattribute 를 통해 추가 속성에 직접 액세스 할 수 있습니다.
답변
Django post save 신호를 사용하여 사용자를 만들 때마다 새 항목을 만들어 사용자 프로필을 간단하게 확장 할 수 있습니다
models.py
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 모델에 정의 된 모든 필드가있는 사용자 추가 양식이 작성됩니다.
models.py
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)
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 = ('user_name',)
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 = "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)
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='add-user'),
]