24. 로그인 상태 표시

25. 로그인 유저와 아닌 유저의 메인페이지를 다르게 노출

  1. 유저가 로그인했을 경우, post:list로 이동
  2. 로그인 하지 않았을 경우, member:signup으로 이동

is_authenticate

# instagram/views.py
def index(request):
    if request.user.is_authenticated:
        return redirect('post:list')
    else:
        return redirect('member:signup')

26. 단위 테스트 추가

index URL로 접근했을 때,

  1. 로그인 하지 않았을 경우 member:signup으로 가는지 확인
  2. 로그인 했을 경우 post:list로 가는지 확인

    ​ 2-1. 테스트용 유저를 생성

    ​ 2-2. 해당 유저 정보로 memeber:login에 POST요청 (로그인)

    ​ 2-3. 이후 위 테스트 실행

# instagram/test.py
from django.test import LiveServerTestCase, Client

from member.models import MyUser

# LiveServerTestCase : 실제 데이터베이스를 사용하고 싶지 않을 때 사용
class IndexTest(LiveServerTestCase):
    def setUp(self):
        self.client = Client()

    def tearDown(self):
        pass

    def test_user_is_not_authenticated_redirect_to_signup(self):
        response = self.client.get('/')
        self.assertRedirects(response, '/member/signup/')

    def test_user_is_authenticated_redirect_to_signup(self):
        # 유저를 로그인 시킨다.
        # 테스트용 유저를 생성한다. (ORM)
        test_username = 'test_user'
        test_password = 'test_password'
        MyUser.objects.create_user(test_username, test_password)

        # member:login으로 POST요청을 보낸다. (self.client.post)
        # views의 login_fbv 함수 참고
        self.client.post(
            '/member/login/',
            {
                'username': test_username,
                'password': test_password,
            }
        )

        # 이후 root url('/')의 response를 받아온다.
        response = self.client.get('/')

        # 해당 response가 /post/로 잘 redirect 되는지 확인
        self.assertRedirects(response, '/post/')

27. 기능 테스트 작성

ft/tests.py 생성 후 작성한다.

테스트 케이스를 통과 못할 경우, 아래의 내용을 확인한다.

# instagram/settings.py
# 정적 파일을 모아서 서빙할 폴더 경로 지정
# 테스트 server 관련 에러 날 경우 반드시 추가해야 함
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')

28. 팔로우/언팔로우 기능 추가

unique_together

class Relationship(models.Model):
    from_user = models.ForeignKey(MyUser, related_name='following_relations')
    to_user = models.ForeignKey(MyUser, related_name='follower_relations')
    created_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = (
            ('from_user', 'to_user')
        )

29. 프로필 페이지에 로그인 유저만 접근 가능하도록 처리

  • 로그인 유/무 확인
  • 사용자가 로그인하지 않은 경우, settings.LOGIN_URL로 redirect
    • 현재 절대 경로를 전달 (예: login/?next=/member/profile/)
  • 사용자가 로그인한 경우 정상적으로 뷰를 보여준다.

The login_required decorator

# instagram/urls.py
LOGIN_URL = 'member:login'
@login_required
def profile(request):
    """
    자신의 게시물 수, 자신의 팔로워 수 자신의, 자신의 팔로잉 수
    context로 전달하여 출력
    :param request:
    :return:
    """
    post_count = Post.objects.filter(author=request.user).count()
    follower_count = request.user.follower_set.count()
    following_count = request.user.following.count()
    context = {
        'post_count': post_count,
        'follower_count': follower_count,
        'following_count': following_count,
    }
    return render(request, 'member/profile.html', context)

과제

30. 프로필 이미지 변경 기능

0. 유저 모델에 img_profile 필드 추가, migrations
1. change_profile_image.html 파일 작성
2. ProfileImageForm 생성
3. 해당 Form을 템플릿에 렌더링
4. request.method == 'POST'일 때 reqest.FILES의 값을 이용해서
request.user의 img_profile을 변경 저장
5. 처리 완료 후 member:profile 이동
6. profile.html에서 user의 프로필 이미지를 img태그를 사용해서 보여줌
을 사용

31. 각 뷰마다 로그인 유무확인 동작 추가 + 테스트 코드 작성

@login_required