0926 TIL

looggi·2022년 9월 26일
1

스파르타 내배캠 AI-3

목록 보기
23/130
post-thumbnail

🌵 로그인 기능 만들기 (wil에 붙이기)

  • 로그인을 처리해줄 함수 만들기
# user/views.py
from django.http import HttpResponse

def sign_in_view(request):
		if request.method == 'POST':
        return HttpResponse("로그인 성공!")
    elif request.method == 'GET':
        return render(request, 'user/signin.html')

->데이터를 받아서 서버로 보내주는 거니까 post

  • signin.html form태그 만들기
<form class="form-area" action="/sign-in/" method="post">
        {% csrf_token %}

-> input에서 받은 값(username, password)를 /sign-in(url)로 보내줌
-> action 과 method 순서는 상관없음!

  • user/views.py 함수 완성해주기
    input값들이 sign-in(url)으로 전달되어 sign_in_view함수 실행
# user/views.py
def sign_in_view(request):
    if request.method == 'POST':
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)

        me = UserModel.objects.get(username=username)  # 사용자 불러오기
        if me.password == password:  # 저장된 사용자의 패스워드와 입력받은 패스워드 비교
            request.session['user'] = me.username  # 세션에 사용자 이름 저장
            return HttpResponse("로그인 성공!")
        else: # 로그인이 실패하면 다시 로그인 페이지를 보여주기
            return redirect('/sign-in')
    elif request.method == 'GET':
        return render(request, 'user/signin.html')

🌵 2주차 숙제

  • 회원가입 중복 방지(sign-up)
if password != password2:
            return render(request, 'user/signup.html')
        else:
            exist_user = UserModel.objects.filter(username=username)
            
            if exist_user:
                return render(request, 'user/signup.html')  # 사용자가 존재하기 때문에 사용자를 저장하지 않고 회원가입 페이지를 다시 띄움
            else:
                new_user = UserModel()
                new_user.username = username
                new_user.password = password
                new_user.bio = bio
                new_user.save()
                return redirect('/sign-in')

-> exist_user에 0이 아닌 어떤 값이 들어있으면(자료형 상관없이) true가 되나??❓

  • 화면에 사용자 이름 출력하기(sign-in)
def sign_in_view(request):
    if request.method == 'POST':
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)

        me = UserModel.objects.get(username=username)  # 사용자 불러오기
        if me.password == password:  # 저장된 사용자의 패스워드와 입력받은 패스워드 비교
            request.session['user'] = me.username  # 세션에 사용자 이름 저장
            return HttpResponse(me.username)
        else:
            return redirect('/login')
    elif request.method == 'GET':
        return render(request, 'user/signin.html')

왜 me.username 이지?? username해도 되는데❓여기선 me.username이랑 username이랑 차이가 없지않나?

🌵 발생한 오류들..

  1. doesnotexist:
    -> 관리자 id/ps로 로그인함(createsuperuser) = 유저모델로 만든 유저가 아니라서(유저모델 만들기 전에 만듬) 있지도 않은 회원정보로 로그인하려고 한게 됨
    -> 그냥 유저 id/ps로 로그인하면 해결됨❗️
  2. multiple return
    -> username이 중복생성돼서 하나만 받아올 수 있는데 두개가 있음
    -> 파이참 database에서 중복되는 id 삭제(행삭제)하고 ⬆︎(commit)해주면 삭제돼서 해결됨❗️

🌞 아침 쪽지시험

Django 프로젝트를 생성하고 실행시켜 접속해보기

<파이참의 프로젝트 자동 생성 및 프로젝트 실행 기능 없이 명령어로만 문제 풀어보기>

python -m venv venv : 가상 환경 생성하기
venv\scripts\activate : (windows)가상 환경 접속하기
source ./venv/bin/activate : (mac) 가상 환경 접속하기
pip install django : django 패키지 설치하기
django-admin startproject $프로젝트이름 . : 현재 경로에 원하는 이름으로 프로젝트 생성하기
python manage.py startapp $앱이름 : 원하는 이름으로 앱 만들기

    1. 프로젝트에 사용될 폴더를 생성하고, 편집기에서 생성한 폴더를 열어주세요
    1. 파이썬 가상 환경을 생성하고 활성화 해주세요
    1. django 패키지를 설치해주세요
    1. spartatest라는 django 프로젝트를 생성해주세요
    1. introduce라는 앱을 생성해주세요
    1. introduce/templates 경로에 간단한 자기소개를 적은 탬플릿 html을 만들어주세요
    1. 127.0.0.1:8000/introduce/ 경로의 페이지에 접속했을 때 자기소개 페이지가 보일 수 있도록 설정해주세요

🌼 참고자료 🌼

https://djangoforbeginners.com/initial-setup/
-> 맥 터미널 설명 짱잘해놓음

파일 수정(없으면 자동 생성): vi filename.html


🦊 장고기초 3주차 (사용자 기능 확장)

  • 장고에서 만든 user vs 내가만든 user -> 합치면 좋겠다!
    -> class의 상속 개념
    -> class b(a): 클래스 b에서 a기능들을 사용할 수 있다
#user/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
#AbstractUser: 장고에서 사용하는 기본유저모델

# Create your models here.
class UserModel(AbstractUser):
    # class UserModel(AbstractUser): UserModel에서 models.Model의 기능을 사용할 수 있음->장고에서 제공하는 AbstractUser 모델을 사용하겠(상속)
    class Meta: # db정보를 넣어주는 곳
        db_table = "my_user"

    bio = models.CharField(max_length=256, default='')
    # 장고의 기본적인 모델을 사용하되 추가적으로 bio를 추가해줬다
  • settings.py에서 먼저 기본적인 세팅 수정
# mySpartaSns/settings.py
AUTH_USER_MODEL = 'user.UserModel'
# 기본적인 장고의 사용자 모델(AUTH_USER_MODEL)을 바꾸겠다-> user앱 안에 있는 usermodel 클래스를 AUTH_USER_MODEL에 넣어주겠다..❓
  • user 모델을 데이터베이스에 적용시키기
    ->python3 manage.py makemigrations

    (venv) HyoZzang@baghyojin-ui-MacBook-Air mySpartaSns % python3 manage.py makemigrations
    Migrations for 'user':
    user/migrations/0002_alter_usermodel_managers_remove_usermodel_created_at_and_more.py
    - Change managers on usermodel
    - Remove field created_at from usermodel
    - Remove field updated_at from usermodel
    - Add field date_joined to usermodel
    - Add field email to usermodel
    - Add field first_name to usermodel
    - Add field groups to usermodel
    - Add field is_active to usermodel
    - Add field is_staff to usermodel
    - Add field is_superuser to usermodel
    - Add field last_login to usermodel
    - Add field last_name to usermodel
    - Add field user_permissions to usermodel
    - Alter field password on usermodel
    - Alter field username on usermodel

->삭제된거 추가된거 대체된거 모두 뜸
->database에 my_user에도 업뎃됨

  • user/views.py sign_up_view 함수 수정
        if password != password2:
            return render(request, 'user/signup.html')
        else:
            exist_user = get_user_model().objects.filter(username=username)
            # <= 같은 코드 exist_user = UserModel.objects.filter(username=username)
            if exist_user:  # 무슨 뜻이지?? 0이 아니면 존재하는거니까??
                return render(request, 'user/signup.html')
            else:
                # new_user = UserModel()
                # new_user.username = username
                # new_user.password = password
                # new_user.bio = bio
                # new_user.save()
                # => 같은 코드 UserModel.objects.create_user(username=username,password=password,bio=bio)
                return redirect('/sign-in')
  • 서버를 실행해서 회원가입을 다시 진행
    -> 이때 새로 만든 id/pw 로는 로그인이 안됨 -> my_user에 저장된 걸 보면 내가 입력했던 암호 대신 복잡한 암호로 저장되어있음 -> 그 두가지 암호가 서로 같다는 확인이 필요함 -> 로그인 함수 수정 필요

  • user/views.py sign_in_view함수 수정

def sign_in_view(request):
    if request.method == 'POST':
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)
        # 화면에서 입력받은 정보(위)를 장고 모듈(auth)로 넣어주고 검사(authenticate)하고 사용자가 있다면 me라는 변수에 정보를 넣어줌
        # 사용자가 있다면 (비어있지 않다면) 로그인시킨다

        # 인증 기능(암호화된 비번과 현재 입력된 비번, 그리고 사용자에 해당하는 비번이 맞는지 확인해줌)
        me = auth.authenticate(request, username=username, password=password)
        # => me = UserModel.objects.get(username=username)->user데이터가 데이터베이스에 있는지 확인하기 (usermodel의 username = post에서 받은 username)
        if me is not None: # authenticate에서 모든걸 확인해주기때문에..
        # -> if me.password == password: 대신
        #     request.session['user'] = me.username 대신->
            auth.login(request, me)
        # session은 사용자 정보를 저장할 수 있는 공간. 그 공간에 user라는 걸 넣는다??? 새로 만든단건가?????? db세션??
            return HttpResponse(username) #답이 me.username 임
        else:
            return redirect('/sign-in')
    elif request.method == 'GET':
        return render(request, 'user/signin.html')

-> 로그인 됨

🌵 로그인 이후 기능

  • template 내부에 tweet 폴더 생성, home.html 파일 추가
  • tweet/views.py
from django.shortcuts import render, redirect

def home(request):
    user = request.user.is_authenticated
    # user가 로그인이 되어있는 상태인지, 인증이 되어있는 상태인지 확인가능
    if user:
        #user 가 있다면
        return redirect('/tweet')
        # 저 url로 리다이렉트
    else:
        return redirect('/sign-in')
        # 없으면 다시 로그인화면으로 


def tweet(request):
    if request.method == 'GET':
        return render(request, 'tweet/home.html')
  • tweet/urls.py
# tweet/urls.py
from django.urls import path
from . import views

urlpatterns = [
    # 그냥 http://127.0.0.1:8000/일때는 view안의 home이란 함수를 보여준다
    path('', views.home, name='home'), # 127.0.0.1:8000 과 views.py 폴더의 home 함수 연결
    path('tweet/', views.tweet, name='tweet') # 127.0.0.1:8000/tweet 과 views.py 폴더의 tweet 함수 연결
]

-> 아직 접속해도 페이지가 안뜸 page not found url pattern 목록에 tweet이 없음

  • myspartasns/urls.py - urlpatterns에 등록하면 ok
path('',include('tweet.urls')),
  • user/views.py
    로그인시 tweet 화면이 뜨도록 수정
# return HttpResponse(username)를 다음과 같이 수정
return redirect('/')

🌵 로그인 이후 페이지 꾸미기

로그인 상태, 사용자 프로필 등 화면에 노출시키기

  • home.html에서 각 부분에 넣을 정보로 태그 내용 수정
 <h5 class="card-title"> {{ user.username }}</h5>
                        <p class="card-text"> {{ user.bio }}</p>
  • base.html에서 form 태그 아래윗부분 수정
<form class="form-inline my-2 my-lg-0">
            {% if not user.is_authenticated %}
{#                로그인이 되었다면#}
                        .
                        .
                        .
			{% else %}
                {{ user.username }} 님 반갑습니다!
{#                 로그인 후에 {{ user.username }}하면 자동으로 들어감#}
            {% endif %}
</form>

🌵 프로젝트 완성도 높이기

  • tweet 화면은 로그인시에만 보여야하는데.. 그냥 주소를 입력하면 바로 보이는 부분 고치기 -> tweet/views.py
def tweet(request):
    if request.method == 'GET':
        user = request.user.is_authenticated
        # 사용자가 로그인이 되어있는지 확인
        if user:
        # 로그인한 사용자가 있다면
            return render(request, 'tweet/home.html')
        else:
        # 직접 들어왓다면 로그인페이지로 이동
            return redirect('/sign-in')
  • 로그인 된 사용자는 회원가입 페이지/ 로그인 페이지를 따로 볼 필요가 없음
    -> 요청방식이 get일 때 무조건 html랜더하는 부분을 수정해야함
    -> user/views.py 에서 sign-in/sign-up 함수 수정
def sign_up_view(request): 
    if request.method == 'GET': 
        user = request.user.is_authenticated
        if user:
            return redirect('/')
        else:
            return render(request, 'user/signup.html') 
            #화면을 보여주고(리퀘스트,템플릿이름)
 elif request.method == 'GET':
        user = request.user.is_authenticated
        if user:
            return redirect('/')
        else:
            return render(request, 'user/signin.html')
  • 로그아웃 기능 만들기
    user/views.py 함수 추가
@login_required #로그인이 반드시 필요
def logout(request):
    auth.logout(request)
    return redirect('/')

-> 함수를 추가 했으니까 urls.py 에 urlpattern 추가

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

-> logout url에 접속할 수 있도록 base.html(네비게이션 바 부분) 코드추가

	{% else %}
             <ul class="navbar-nav mr-auto">
                 <li class="nav-item active">
                       <span class="nav-link">
                        {{ user.username }}님 반갑습니다!
                    </span>
                  </li>
                 <li class="nav-item active">
                    <a class="nav-link" href="/logout"> 로그아웃 </a>
                 </li>
             </ul>
 	{% endif %}
  • 게시글 작성하기 기능
   <form action = '/tweet/' method ='post'>
 {%  csrf_token %}
    <div class="form-group mb-2">
       <textarea class="form-control" style="resize: none" name='my-content' id="my-content"></textarea>
   </div>
   <button type="submit" class="btn btn-primary" style="float:right;">작성하기</button>
   </form>

-> 여기서 form 태그 사이의 name 부분을 이용해서 tweet/views.py에서

    elif request.method == 'POST':
        user = request.user
        my_tweet = TweetModel()
        my_tweet.author = user
        my_tweet.content = request.POST.get('my-content','')
        my_tweet.save()
        return redirect('/tweet')
  • 게시글 읽기/작성...

🐢 거북이반

render: template(html)으로 그림을 그린다
redirect: 다른곳으로(url) 보낸다
아직은 어떤 차이가 있는지 잘 모르겠다..
❓❓❓❓❓❓❓❓❓❓❓❓

profile
looooggi

0개의 댓글