"회원관리 2-1. 커스텀유저(Profile 이용)"의 두 판 사이의 차이
둘러보기로 가기
검색하러 가기
(→모델작성) |
|||
(같은 사용자의 중간 판 4개는 보이지 않습니다) | |||
13번째 줄: | 13번째 줄: | ||
일반적인 프로필 모델이라면 위 과정만으로도 구현이 끝난다. | 일반적인 프로필 모델이라면 위 과정만으로도 구현이 끝난다. | ||
− | 다만, 이번엔 여러 계정을 하나의 프로필에 엮어줄 예정이라, AbstractBaseUser를 이용하여 다음과 같은 방식으로 짜주자. 다음 문서를 참고하자. <syntaxhighlight lang="python"> | + | 다만, 이번엔 여러 계정을 하나의 프로필에 엮어줄 예정이라, AbstractBaseUser를 이용하여 다음과 같은 방식으로 짜주자. 다음 문서를 참고하자. [http://id8436.iptime.org:2786/mediawiki/index.php/%ED%9A%8C%EC%9B%90%EA%B4%80%EB%A6%AC_2._%EC%BB%A4%EC%8A%A4%ED%85%80%EC%9C%A0%EC%A0%80(AbstractUser_%EC%9D%B4%EC%9A%A9) 커스텀 유저] <syntaxhighlight lang="python"> |
+ | from django.db import models | ||
+ | from django.contrib.auth.models import BaseUserManager, AbstractBaseUser | ||
+ | |||
class User(AbstractBaseUser): | class User(AbstractBaseUser): | ||
identifier = models.CharField(max_length=20, unique=True) | identifier = models.CharField(max_length=20, unique=True) | ||
is_active = models.BooleanField(default=True) | is_active = models.BooleanField(default=True) | ||
+ | is_staff = models.BooleanField(default=False) | ||
is_admin = models.BooleanField(default=False) | is_admin = models.BooleanField(default=False) | ||
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, blank=True) # 연결할 프로필모델. 아래에서 정의. | profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, blank=True) # 연결할 프로필모델. 아래에서 정의. | ||
27번째 줄: | 31번째 줄: | ||
def __str__(self): | def __str__(self): | ||
return self.identifier | return self.identifier | ||
+ | |||
+ | def has_module_perms(self, app_label): | ||
+ | '''앱 라벨을 받아, 해당 앱에 접근 가능한지 파악''' | ||
+ | return True | ||
+ | def has_perm(self, perm, obj=None): | ||
+ | '''권한 소지여부를 판단하기 위한 메서드''' | ||
+ | return True | ||
</syntaxhighlight>그리고 프로필 계정은 필요에 따라 다음과 같이 짠다. User에서 참고해야 하므로 User모델보다 위에 위치하게 해주자.<syntaxhighlight lang="python"> | </syntaxhighlight>그리고 프로필 계정은 필요에 따라 다음과 같이 짠다. User에서 참고해야 하므로 User모델보다 위에 위치하게 해주자.<syntaxhighlight lang="python"> | ||
class Profile(models.Model): | class Profile(models.Model): | ||
37번째 줄: | 48번째 줄: | ||
email_active = models.BooleanField(default=False) # 이메일 검증여부 | email_active = models.BooleanField(default=False) # 이메일 검증여부 | ||
</syntaxhighlight>이렇게 하면 user.profile.username 같은 방식으로 프로필 속성에 접근할 수 있다. | </syntaxhighlight>이렇게 하면 user.profile.username 같은 방식으로 프로필 속성에 접근할 수 있다. | ||
+ | |||
+ | 이후 admin.py 등을 작성하고 관리자 계정 작성 및 로그인 하여 잘 작성되었는지 확인한다. | ||
+ | |||
+ | === admin.py === | ||
+ | <syntaxhighlight lang="python"> | ||
+ | from django.contrib import admin | ||
+ | from .models import User, Profile # 직접 등록한 모델 | ||
+ | |||
+ | @admin.register(User) | ||
+ | class UserAdmin(admin.ModelAdmin): | ||
+ | list_display = ('identifier',) | ||
+ | exclude = ('password',) # 사용자 상세 정보에서 비밀번호 필드를 노출하지 않음 | ||
+ | |||
+ | @admin.register(Profile) | ||
+ | class UserAdmin(admin.ModelAdmin): | ||
+ | list_display = ('nickname',) | ||
+ | </syntaxhighlight> | ||
== 계정에서 프로필 생성 == | == 계정에서 프로필 생성 == | ||
54번째 줄: | 82번째 줄: | ||
=== url 추가 === | === url 추가 === | ||
다음과 같이 url을 추가해준다.<syntaxhighlight lang="python"> | 다음과 같이 url을 추가해준다.<syntaxhighlight lang="python"> | ||
− | path(' | + | path('profile_create/', views.profile_create, name='profile_create'), |
</syntaxhighlight> | </syntaxhighlight> | ||
=== view 추가 === | === view 추가 === | ||
다음과 같이 뷰를 추가한다.<syntaxhighlight lang="python"> | 다음과 같이 뷰를 추가한다.<syntaxhighlight lang="python"> | ||
+ | from .models import Profile | ||
+ | |||
@login_required() | @login_required() | ||
− | def | + | def profile_create(request): |
− | + | if request.method == "POST": | |
+ | form = Profile_create_form(request.POST) | ||
+ | if form.is_valid(): | ||
+ | username = form.cleaned_data.get('identifier') # 유저아이디를 입력받는다. | ||
+ | raw_password = form.cleaned_data.get('password') # 패스워드를 입력받는다. | ||
+ | user = authenticate(username=username, password=raw_password) # 인증 진행 | ||
+ | if user: # 유저모델이 반환된다면.. 프로필 모델에 저장한다. | ||
+ | profile = Profile() | ||
+ | profile.username = form.cleaned_data.get('username') | ||
+ | profile.nickname = form.cleaned_data.get('nickname') | ||
+ | profile.email = form.cleaned_data.get('email') | ||
+ | profile = profile.save() | ||
+ | request.user.profile = profile # 해당 로그인한 유저의 프로필을 이 프로필로 채운다. | ||
+ | request.user.save() | ||
+ | return redirect('account:profile') | ||
+ | else: | ||
+ | form.add_error('identifier','비밀번호 혹은 아이디가 다릅니다.') # 인증이 안되면 필드에러를 발생시킨다. | ||
+ | else: | ||
+ | form = Profile_create_form() | ||
+ | context = {'form': form, | ||
+ | } | ||
+ | return render(request, 'account/profile_create.html', context) | ||
+ | |||
</syntaxhighlight> | </syntaxhighlight> | ||
− | === view에서 사용할 | + | === view에서 사용할 form 추가 === |
− | <syntaxhighlight lang="python"> | + | 계정 검증을 해야하기 때문에 모델에 기반한 폼이 아니라 일반 폼으로 제작한다.<syntaxhighlight lang="python"> |
− | + | class Profile_create_form(forms.Form): | |
− | class | + | identifier = forms.CharField() |
− | + | password = forms.PasswordInput() | |
− | + | username = forms.CharField(max_length=10) | |
− | + | nickname = forms.CharField(max_length=10) | |
+ | email = forms.EmailField() | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[[분류:장고 기능구현(초급)]] | [[분류:장고 기능구현(초급)]] |
2021년 11월 7일 (일) 18:32 기준 최신판
1 개요[편집 | 원본 편집]
프로필은 또 다른 DB 요청이 있다는 점에서 불필요한 과정이 늘기도 하지만... SNS 계정을 한 프로필 내에서 관리하기 위해 사용해본다.
그리고, 일단 간단하다.
2 모델작성[편집 | 원본 편집]
기본적으로 프로필 모델을 작성하고 다음과 같이 1:1 연결을 하는 것이 일반적이다.
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
3 더 나아가기[편집 | 원본 편집]
일반적인 프로필 모델이라면 위 과정만으로도 구현이 끝난다.
다만, 이번엔 여러 계정을 하나의 프로필에 엮어줄 예정이라, AbstractBaseUser를 이용하여 다음과 같은 방식으로 짜주자. 다음 문서를 참고하자. 커스텀 유저
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
class User(AbstractBaseUser):
identifier = models.CharField(max_length=20, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, blank=True) # 연결할 프로필모델. 아래에서 정의.
# 프로필이 사라지면 사용자 모델도 한꺼번에 다 없어지게끔!
objects = UserManager() # 회원가입을 다룰 클래스를 지정한다.
USERNAME_FIELD = 'identifier' # 식별자로 사용할 필드.
REQUIRED_FIELDS = [] # 회원가입 때 필수 입력필드.
def __str__(self):
return self.identifier
def has_module_perms(self, app_label):
'''앱 라벨을 받아, 해당 앱에 접근 가능한지 파악'''
return True
def has_perm(self, perm, obj=None):
'''권한 소지여부를 판단하기 위한 메서드'''
return True
그리고 프로필 계정은 필요에 따라 다음과 같이 짠다. User에서 참고해야 하므로 User모델보다 위에 위치하게 해주자.
class Profile(models.Model):
'''계정모델에서 연결하여 상위에 있는, 하위 SNS계정을 종합하는 프로필.'''
# 유저정보 관련
username = models.CharField(max_length=10) # 실명을 기입하게끔 하자.
nickname = models.CharField(max_length=10, unique=True, null=True, blank=False) # 드러날 식별자. 변경 가능하지만, 유일하다.
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now=True)
email_active = models.BooleanField(default=False) # 이메일 검증여부
이렇게 하면 user.profile.username 같은 방식으로 프로필 속성에 접근할 수 있다.
이후 admin.py 등을 작성하고 관리자 계정 작성 및 로그인 하여 잘 작성되었는지 확인한다.
3.1 admin.py[편집 | 원본 편집]
from django.contrib import admin
from .models import User, Profile # 직접 등록한 모델
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
list_display = ('identifier',)
exclude = ('password',) # 사용자 상세 정보에서 비밀번호 필드를 노출하지 않음
@admin.register(Profile)
class UserAdmin(admin.ModelAdmin):
list_display = ('nickname',)
3.2 계정에서 프로필 생성[편집 | 원본 편집]
회원가입 후 프로필을 생성하여야 한다.
3.2.1 탬플릿 추가[편집 | 원본 편집]
base.html 등에 프로필이 없는 경우, 프로필을 생성하고 활동할 수 있게끔 코드를 넣는다.
{% if user.profile %}
{% else %}
<div class="alert alert-danger">
<h1><strong>프로필을 등록해야 글을 쓸 수 있습니다.</strong></h1>
<h2><a href="{% url 'account:create_profile' %}">프로필 생성</a></h2>
</div>
{% endif %}
3.2.2 url 추가[편집 | 원본 편집]
다음과 같이 url을 추가해준다.
path('profile_create/', views.profile_create, name='profile_create'),
3.2.3 view 추가[편집 | 원본 편집]
다음과 같이 뷰를 추가한다.
from .models import Profile
@login_required()
def profile_create(request):
if request.method == "POST":
form = Profile_create_form(request.POST)
if form.is_valid():
username = form.cleaned_data.get('identifier') # 유저아이디를 입력받는다.
raw_password = form.cleaned_data.get('password') # 패스워드를 입력받는다.
user = authenticate(username=username, password=raw_password) # 인증 진행
if user: # 유저모델이 반환된다면.. 프로필 모델에 저장한다.
profile = Profile()
profile.username = form.cleaned_data.get('username')
profile.nickname = form.cleaned_data.get('nickname')
profile.email = form.cleaned_data.get('email')
profile = profile.save()
request.user.profile = profile # 해당 로그인한 유저의 프로필을 이 프로필로 채운다.
request.user.save()
return redirect('account:profile')
else:
form.add_error('identifier','비밀번호 혹은 아이디가 다릅니다.') # 인증이 안되면 필드에러를 발생시킨다.
else:
form = Profile_create_form()
context = {'form': form,
}
return render(request, 'account/profile_create.html', context)
3.2.4 view에서 사용할 form 추가[편집 | 원본 편집]
계정 검증을 해야하기 때문에 모델에 기반한 폼이 아니라 일반 폼으로 제작한다.
class Profile_create_form(forms.Form):
identifier = forms.CharField()
password = forms.PasswordInput()
username = forms.CharField(max_length=10)
nickname = forms.CharField(max_length=10)
email = forms.EmailField()