8번째 줄: |
8번째 줄: |
| class Profile(models.Model): | | class Profile(models.Model): |
| user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) | | user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) |
− | </syntaxhighlight>일반적인 프로필 모델이라면 위 과정만으로도 구현이 끝난다. | + | </syntaxhighlight> |
| | | |
− | 다만, 이번엔 여러 계정을 하나의 프로필에 엮어줄 예정이라, AbstractBaseUser를 이용하여 다음과 같은 방식으로 짜주자. 다음 문서를 참고하자. <syntaxhighlight lang="python"> | + | = 더 나아가기 = |
− | class User(AbstractBaseUser): # 사용자들..!! | + | 일반적인 프로필 모델이라면 위 과정만으로도 구현이 끝난다. |
− | # 계정관련
| + | |
− | identifier = models.CharField(max_length=20, unique=True, null=True, blank=False) # 로그인 할 때 사용할 식별자. | + | 다만, 이번엔 여러 계정을 하나의 프로필에 엮어줄 예정이라, 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"> |
− | email = models.EmailField(max_length=60) | + | 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) # 연결할 프로필모델. 아래에서 정의. | | profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, blank=True) # 연결할 프로필모델. 아래에서 정의. |
| # 프로필이 사라지면 사용자 모델도 한꺼번에 다 없어지게끔! | | # 프로필이 사라지면 사용자 모델도 한꺼번에 다 없어지게끔! |
| + | objects = UserManager() # 회원가입을 다룰 클래스를 지정한다. |
| | | |
− | # 유저권한 관련
| + | USERNAME_FIELD = 'identifier' # 식별자로 사용할 필드. |
− | is_active = models.BooleanField(default=True) # 장고 필수필드. 이게 false면 로그인 자체가 안됨.
| + | REQUIRED_FIELDS = [] # 회원가입 때 필수 입력필드. |
− | is_staff = models.BooleanField(default=False)
| |
− | is_admin = models.BooleanField(default=False) # 장고 필수필드
| |
− | is_superuser = models.BooleanField(default=False)
| |
− | | |
− | USERNAME_FIELD = 'identifier' # 어떤 것을 로그인 때의 식별자로 사용할 것인가. | |
− | REQUIRED_FIELDS = ['email', ] # 입력할 때 필수입력 필드 지정. | |
| | | |
| def __str__(self): | | def __str__(self): |
− | return self.email#self.nickname +'.' +self.identifier | + | return self.identifier |
− | def has_perm(self, perm, obj=None): # 이건 뭐람;;?
| + | |
− | return self.is_admin
| |
| def has_module_perms(self, app_label): | | def has_module_perms(self, app_label): |
| + | '''앱 라벨을 받아, 해당 앱에 접근 가능한지 파악''' |
| return True | | return True |
− | | + | def has_perm(self, perm, obj=None): |
− | objects = AccountManager() # 회원가입을 다루는 클래스. | + | '''권한 소지여부를 판단하기 위한 메서드''' |
− | </syntaxhighlight>그리고 프로필 계정은 필요에 따라 다음과 같이 짠다.<syntaxhighlight lang="python"> | + | return True |
| + | </syntaxhighlight>그리고 프로필 계정은 필요에 따라 다음과 같이 짠다. User에서 참고해야 하므로 User모델보다 위에 위치하게 해주자.<syntaxhighlight lang="python"> |
| class Profile(models.Model): | | class Profile(models.Model): |
| '''계정모델에서 연결하여 상위에 있는, 하위 SNS계정을 종합하는 프로필.''' | | '''계정모델에서 연결하여 상위에 있는, 하위 SNS계정을 종합하는 프로필.''' |
45번째 줄: |
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> |
| | | |
| == 계정에서 프로필 생성 == | | == 계정에서 프로필 생성 == |
55번째 줄: |
75번째 줄: |
| <div class="alert alert-danger"> | | <div class="alert alert-danger"> |
| <h1><strong>프로필을 등록해야 글을 쓸 수 있습니다.</strong></h1> | | <h1><strong>프로필을 등록해야 글을 쓸 수 있습니다.</strong></h1> |
− | <h2><a href="{% url 'membership:create_profile' %}">프로필 생성</a></h2> | + | <h2><a href="{% url 'account:create_profile' %}">프로필 생성</a></h2> |
| </div> | | </div> |
| {% endif %} | | {% endif %} |
62번째 줄: |
82번째 줄: |
| === url 추가 === | | === url 추가 === |
| 다음과 같이 url을 추가해준다.<syntaxhighlight lang="python"> | | 다음과 같이 url을 추가해준다.<syntaxhighlight lang="python"> |
− | path('create_profile/', views.create_profile, name='create_profile'), | + | 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 create_profile(request): | + | def profile_create(request): |
− | pass | + | 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에서 사용할 profile 추가 === | + | === view에서 사용할 form 추가 === |
− | <syntaxhighlight lang="python"> | + | 계정 검증을 해야하기 때문에 모델에 기반한 폼이 아니라 일반 폼으로 제작한다.<syntaxhighlight lang="python"> |
− | from .models import Profile
| + | class Profile_create_form(forms.Form): |
− | class ProfileForm(forms.ModelForm): | + | identifier = forms.CharField() |
− | class Meta: | + | password = forms.PasswordInput() |
− | model = Profile
| + | username = forms.CharField(max_length=10) |
− | fields = ['username', 'email', 'nickname']
| + | nickname = forms.CharField(max_length=10) |
| + | email = forms.EmailField() |
| </syntaxhighlight> | | </syntaxhighlight> |
| [[분류:장고 기능구현(초급)]] | | [[분류:장고 기능구현(초급)]] |