해리의 데브로그

Django 26 - 팔로우 기능, 유저모델(AbstractUser) 상속 (1)

|

팔로우 기능, 유저모델(AbstractUser) 상속 (1)

Django 21 M:N 관계설정 포스팅에서 좋아요 기능을 통해 M:N 관계를 설정하는 코드를 작성해보았음. M:N 관계설정을 이용하여 인스타그램의 팔로우 기능을 구현하고 Django 내장 유저모델을 상속받아보도록 하자.

Django user 모델 확장의 4가지 방법

  1. Proxy Model: 기존의 User 모델을 그대로 사용하되, 일부 동작을 변경하는데만 사용
  2. User Profile: 하나의 새로운 모델을 정의한 후, User 모델과 1:1 관계설정(프로필 모델 참조)
  3. AbstractBaseUser: 완전한 새로운 User 모델을 만들때 사용
  4. AbstractUser: 기존의 User 모델을 사용하되, 추가적인 정보를 더 넣고 싶을 때 사용. 2번 방법은 추가로 클래스를 생성하지만, 이 방법의 경우 추가로 클래스를 생성하지는 않음.

관련 내용 참조

accounts/models.py

  • Django 내장 유저 모델을 상속받아 사용
    • 기존의 User 모델을 사용하면서 추가적인 정보만 넣으므로 4번 방법(AbstractUser) 을 이용
    • 사용을 위해 import
from django.conf import settings
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    followers = models.ManyToMnayField(settings.AUTH_USER_MODEL, related_name='followings')

settings.py

  • accounts/models.py 내 AbstractUser를 상속받은 User 모델을 새로 만들었으므로, 이 모델을 유저모델로 사용하기 위해 settings.py 내 추가 설정
  • 유저모델을 변경하였으므로, DB & migration 파일을 삭제 하여 갈아엎은 후, 마이그레이션 재설정
AUTH_USER_MODEL = 'accounts.User'

현재 상태에서 회원가입을 진행할 시에는 아래와 같이 에러가 발생한다.

AttributeError at /accounts/signup/ Manager isn’t available; ‘auth.User’ has been swapped for ‘accounts.User’)

views.py/signup 함수에서 사용하는 UserceationForm 이 문제인데, 이 폼은 장고에서 기본적으로 제공하는 폼으로, 장고 기본 유저모델을 기반으로 만들어져있음. 그러나 settings.py 에서 커스텀 유저모델을 기본 모델로 설정을 변경하였기 때문에 에러가 발생. 따라서, 우리가 만든 유저모델을 기반으로 사용하기위해서는 해당 폼을 커스터마이징할 필요가 있음.

UserCreationForm 커스터마이징

forms.py

  • UserCreationForm 을 상속받아 CustomUserCreationForm 이라는 커스터마이징된 폼 생성
    • get_user_model() 은 settings.py 에서 설정한 유저모델을 가져옴.
    • fields에는 UserCreationForm.Meta.fields 를 입력
from django.contrib.auth.forms import UserCreationForm

class CustomUserCreationForm(UserCreationForm):
    class Meta(UserCreationForm.Meta):
        models = get_user_model()
        fields = UserCreationForm.Meta.fields

views.py

  • signup 함수 내에서 사용하는 UserCreationFormCustomUserCreationForm 으로 변경
    • 사용을 위해 import
from .forms import CustomUserCreationForm

def signup(request):
    if request.user.is_authenticated:
        return redirect('posts:list')
        
    if request.method == 'POST':
        signup_form = CustomUserCreationForm(request.POST)
        if signup_form.is_valid():
            user = signup_form.save()
            Profile.objects.create(user=user) 
            auth_login(request, user)
            return redirect('posts:list')
    
    else:
        signup_form = CustomUserCreationForm()
    
    return render(request, 'accounts/signup.html', {'signup_form':signup_form})

urls.py

  • 팔로우 기능에 대한 urlpattern 설정
urlpatterns = [
    path('<int:user_id>/follow/', views.follow, name='follow'),
]

Django 25 - 1:1 관계 설정 / 프로필 모델 구현

|

Django 24 - 유저 정보 수정 & 삭제

|

2019년 6월 4주차 TIL

|

2019-06-17

  • 어제 공부한 이미지 폼셋에 이어, 여러장의 사진을 Carousel을 이용하여 자동으로 넘어가는 코드 복습을 진행하였음.
  • forloop.counter 은 반복문의 횟수를 카운터할 때 쓰는 장고템플릿 문법
  • Carousel을 사용할 때, Carousel의 id값을 적용해야하는데, 고유의값을 사용하기 위해 post_id를 활용하였음. 이때, id값에는 숫자만 입력할 경우에는 작동하지 않으므로 문자열을 섞어서 사용해야함.
  • 깃허브 블로그 Liquid tag error를 피하기 위해 raw & endraw 를 장고 & 진자템플릿 문법이 사용되는데마다 쓰고있다. 블로그에서는 raw & endraw 부분이 자동으로 생략되어 raw한 코드들만 보이긴한데, README 파일에서 코드블럭 내용을 보면 raw &endraw 부분때문에 매우지저분해보인다. raw &endraw를 삽입하는 1차원적인 방법말고 근본적인 방법이 없는지 찾아봐야겠다.

2019-06-19

  • 사용자 CRUD 중 수정과 삭제에 해당하는 U,D에 대해 공부하였음.
  • UserChangeForm에는 많은 정보가 담겨있는데, 필요한 필드에 대해서만 사용자 정보를 수정하기 위해 UserchangeForm을 상속받아 CustomUserChangeForm 을 새로 생성하였음.
  • 비밀번호 변경에는 PasswordChangeForm 사용. 다른 폼과 다르게 request.user, request.POST 순으로 인자를 받는데, 혼란이 올 수 있으니, 키워드 인자명을 함께 써주는게 나은 듯 하다.
password_change_form = PasswordChangeForm(request.user, request.POST)
#키워드인자명 함께 사용
password_change_form = PasswordChangeForm(user=request.user, data=request.POST)
  • update_session_auth_hash 는 비밀번호 수정 후에도 로그인을 유지하게 하는 메서드. 세션에 있는 로그인 정보 해쉬를 업데이트 할때 사용함.

2019-06-20

  • Django에서 유저모델과 1:1로 대응하는 프로필 모델을 구현해보았음.
  • 1:1 관계설정에서는 OneToOneField 를 사용함. 말그대로 프로필 처럼, 기존의 유저모델은 보존하면서, 유저모델의 기반의 또다른 하나의 모델을 사용할 때 유용할 듯 하다.
  • 전반적인 코드 작성은 기본적인 MTV 패턴을 구현하는 방식을 사용함.

2019-06-21

  • 유저모델을 상속받아서 M:N 관계를 이용하여 팔로우 기능을 구현하는 챕터를 다시 공부하였음. Django에서 기본 유저 모델을 상속받아 확장하는 방법이 다양한데, 기본적으로 아래와 같이 4가지가 있고, 미세하게 다르다는 것을 알게 되었다. 팔로우 기능의 경우, 기본 유저모델을 사용하면서, follow에 대한 필드만을 추가하므로 AbstractUser 모델을 상속받아 모델을 작성하였음.
    • Proxy Model: 기존의 User 모델을 그대로 사용하되, 일부 동작을 변경하는데만 사용
    • User Profile: 하나의 새로운 모델을 정의한 후, User 모델과 1:1 관계설정(프로필 모델 참조)
    • AbstractBaseUser: 완전한 새로운 User 모델을 만들때 사용
    • AbstractUser: 기존의 User 모델을 사용하되, 추가적인 정보를 더 넣고 싶을 때 사용. 2번 방법은 추가로 클래스를 생성하지만, 이 방법의 경우 추가로 클래스를 생성하지는 않음.
  • 유저모델을 변경했을 경우, 커스터마이징된 유저모델을 기본유저모델로 사용한다는 코드를 settings.py에 추가해야함. => AUTH_USER_MODEL = ‘어플리케이션명.모델명’ 예) accounts.User
  • UserCreationForm 은 장고의 기본 User 모델을 사용하기 때문에, 에러를 피하기 위해 커스터마이징 필요

2019-06-22

  • 어제에 이어서 팔로우 기능에 대한 MTV 패턴을 복습하였음.
  • 좋아요 기능과 마찬가지로 M:N 관계의 경우, 리스트의 형태로 저장되기때문에, 이를 활용하여 같은 기능에 대하여 좋아요/좋아요 취소를 분기문을 통해 나타낼 수 있음.
  • values_list 는 쿼리셋을 튜플의 형태로 변경할 떄 사용하는 메소드임. 하나의 필드만 넣을 경우, flat 인자를 넣을 수 있으며 flat=True는 결과값을 single values로 변경시킴.
  • itertools.chain() 은 여러개의 쿼리셋을 하나의 리스트로 합칠때 사용하는 메서드. 이때 인자는 iterable가능한 데이터 타입이 들어가야함. 따라서 iterable하지 않을 경우, 타입 변경을 통해 iterable 하게 바꿔줘야함!

2019-06-23

  • 장고 복습의 마지막 챕터인 Django-RestFramework 를 이용한 백엔드 API 서버를 구현에 대해 공부를 하고 코드를 작성해보았다.
  • DRF(Django RestFramework): RESTful API 서버 구축을 쉽게 도와주는 라이브러리
  • Django에서 사용하는 복잡한 데이터를 클라이언트 측에서 사용하기 위해서는 JSON이나 XML으로 데이터의 형태(DRF에서는 string이라고 지칭함)로 변환을 해야하는데, serializer가 이 기능을 함.
  • @api_view는 어떠한 HTTP Methods를 허용할건지를 설정할 때 사용하는 데코레이터
  • 이 프로젝트에서는 Artist와 Music 모델이 1:N 관계로 이루어져있는데, serializer에서 Artist 모델을 토대로 Artist에 대한 모든 Music을 갖고올 때, 필드명을 music_set으로 설정하는 코드를 다시 살펴보았다. 1에서 N으로 접근할때, artist.music_set.all() 처럼 사용하기 위해 필드명을 강제로 지정하는 듯 한데, 반드시 이 조건 지켜야하는지 궁금하다. 내일 다시 장고 프로젝트를 새로만들어볼 때 테스트를 해봐야겠다.

Django 23 - 이미지 다루기 2 (Carousel)

|