"회원관리 2-1. 커스텀유저(Profile 이용)"의 두 판 사이의 차이

Pywiki
둘러보기로 가기 검색하러 가기
20번째 줄: 20번째 줄:
 
     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)  # 연결할 프로필모델. 아래에서 정의.
30번째 줄: 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):

2021년 11월 6일 (토) 11:15 판

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 같은 방식으로 프로필 속성에 접근할 수 있다.

3.1 계정에서 프로필 생성

회원가입 후 프로필을 생성하여야 한다.

3.1.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.1.2 url 추가

다음과 같이 url을 추가해준다.

path('profile_create/', views.profile_create, name='profile_create'),

3.1.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.1.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()