django user app (study)

1.models

from django.db import models

# Create your models here.


class User(models.Model):  
# 클래스 만들때 장고에서 제공하는 모델스의 모델을 상속받아야함.
    username = models.CharField(max_length=34, verbose_name='사옹자명')
    useremail = models.EmailField(max_length=128, verbose_name='사용자 이메일')
    password = models.CharField(max_length=64, verbose_name='비밀번호')
    registered_dttm = models.DateTimeField(
        auto_now_add=True, verbose_name='등록시간')
    # dttm = date time
    # verbose_name 의 설정으로 admin 사이트에 나오는 이름명 설정이됌.
    # 이메일필드를 사용

    def __str__(self):
        return self.username
    # user object 라고 나오던게 이제 username 의 객체 으로 나옴
    # 파이썬에는 클래스가 문자열로 변환됬을떄 어떻게 변환을 할지 결정하는 내장함수가 있고,
    # 그것이 __str__ 이다.
    # 내가 가진 유저네임으로 반환하겠다고 설정하는거임.
    # 그러면 이제 RM이라고 잘나옴.

    class Meta:
        db_table = 'sihwan_user'
        verbose_name = 'BTS'
        verbose_name_plural = 'BTS'  # 복수형제거
# 테이블명을 지정하는 이유
# 기본적으로 생성되는 앱들과 구분해서 테이블명을 만들기 위함임.

추가설명

1.EmailField

class EmailField(max_length=254, **options)

A CharField that checks that the value is a valid email address using EmailValidator.
EmailValidator
2.auto_now , auto_now_add
생성일자 - 최초 등록시에만 저장, 갱신되지 않는 정보
최종수정일자 - 수정시 갱신

수정일자 : auto_now=True 사용
auto_now=True 는 django model 이 save 될 때마다 현재날짜(date.today()) 로 갱신됩니다.
"될 때 마 다"
주로 최종수정일자 field option 으로 주로 사용됩니다.

생성일자 : auto_now_add=True 사용
auto_now_add=True 는 django model 이 최초 저장(insert) 시에만 현재날짜(date.today()) 를 적용합니다.
3.

def __str__(self):
        return self.username


있고 없고의 서비스 차이

2.forms

from django import forms
from .models import User
from django.contrib.auth.hashers import check_password


class LoginForm(forms.Form):
    username = forms.CharField(
        error_messages={'required': '아이디를 입력해주세요'}, max_length=32, label="사용자 이름")
    password = forms.CharField(error_messages={
                               'required': '아이디를 입력해주세요'}, widget=forms.PasswordInput, label="비밀번호")
# widget=forms.PasswordInput 비밀번호를 패스워드 타입으로 위젯을 직접 지정했음.
# 이제 암호도 숨겨져서 나옴
# 에러메시지 입력하는거, 방금 메시지가 리콰이어드라는 키에 들어있기떄문에 저렇게하는거임.
    # 이제 비밀번호 일치하는 여부도 확인. 이미 만들어져 있는 함수를 사용할것임 .ㄱ ㅡ래서 슈퍼를 통해 기존에 폼안에 들어있던 클린함수를 먼저호출

    def clean(self):
        cleaned_data = super().clean()
        username = cleaned_data.get('username')
        password = cleaned_data.get('password')

        if username and password:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                self.add_error('username', '아이디가 없습니다.')
                return
            if not check_password(password, user.password):
                # 입력받은값, 모델에 있는값
                # 폼안에 기본적으로 있는 add error 함수임. 특정 필드에 에러를 넣는 함수임
                self.add_error('password', '비밀번호가 틀렸습니다')
            else:
                # 셀프를 통해서 클래스변수안에 들어가게된다. 그럼 밖에서도 접근이 가능하다.
                self.user_id = user.id

# form 안에서 데이터를 어떻게 검증할건지에 대해서 클래스를 하나 만들게되고 뷰에서는 코드가 깔끔해짐.
# 로그인 폼을 만들고 이게 정상적인지 확인하고 정상적이라면 어디로 가라. 굉장히 심플해진다.

추가설명
1.error_messages
error_messages: 해당 필드의 에러 메시지 목록. 필요하면 문구를 수정할 수 있다.

3.views

from django.shortcuts import render, redirect
from .models import User
from django.http import HttpResponse
from django.contrib.auth.hashers import make_password, check_password
from .forms import LoginForm
# 장고에 이미 포함되있는 ...이안에 check password도 있음 hasher 안에
# Create your views here.


def home(request):
    user_id = request.session.get('user')
    if user_id:
        user = User.objects.get(pk=user_id)
        # return HttpResponse(user.username)
    # return HttpResponse('HOME')
    return render(request, 'home.html')


def login(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():                 # form 에 기본적으로 있는 함수임 . form에 데이터를 넣으면 여기서 검사가 될것임.
            # 메시지도 필요해서 login.html에 추가해줫음 레드부분. 함수의 기능임.

            # 세션  (세션에 데이터넣을땐 키를넣고..아이디가 없으니 가져와야함.)
            request.session['user'] = form.user_id  # is valid에 의해 이미 검증이된거임
            return redirect('/')
    else:
        form = LoginForm()
    # if request.method == 'GET':
    #    return render(request, 'login.html')  # 연결
    # elif request.method == 'POST':
    #    username = request.POST.get('username', None)
    #    password = request.POST.get('password', None)

    #    res_data = {}
    #   if not (username and password):
    #      res_data['error'] = "값이 누락되었습니다."
    # else:
    #    # (필드명 = 값) 입력받은 유저네임을 유저네임이라는 변수에 담아놨기때문에 .현재.
    #    user = User.objects.get(username=username)
    #    # (입력받은 비밀번호, 모델로부터 가져온 비밀번호값.)
    #    if check_password(password, user.password):
    #        request.session['user'] = user.id
    #        # 방금 로그인한 유저의 아이디값을 세션에 저장한것임. 넣은거로만 저장이됌
    #        return redirect('/')  # 일반적으로 / 로해두면 만들고있는 웹의 홈으로 간다.
    #        # 비밀번호가 일치하면 로그인처리
    #        # 진짜 로그인처럼되려면 세션이 필요함.
    #        # 로그인이 끝났으면 이제 다른 창으로 가야지 홈으로 가던가. redirect

    # pass
    #    else:
    #        res_data['error'] = " 비밀번호 틀림"
    # return render(request, 'login.html', res_data)
    return render(request, 'login.html', {'form': form})
    # 메세지를 전달하기 위해 렌더를 할때  딕셔너리변수를 전달하기 위해 res_data를 추가.


def logout(request):
    if request.session.get('user'):
        del(request.session['user'])
    return redirect('/')


def register(request):
    if request.method == "GET":
        return render(request, 'register.html')
        # 아직 아무것도 전달한 데이터가 없어서 처음 접속했을때 나오는것임.
    elif request.method == "POST":
        username = request.POST.get('username', None)
        useremail = request.POST.get('useremail', None)
        password = request.POST.get('password', None)
        re_password = request.POST.get('re-password', None)
        # 딕셔너리에서 그 키값을 가지고 오는데 그 키값없으면 기본값으로 none으로 지정.
        # 근데 [] 였다가 () 로 바꿔버리는이유점
        # 그리고 get을 갑자기 왜 붙임.
        # 만약에 사용자이름 비번, 비번확인 다 입력안하고 포스트요청하면 에러안날것임.
        # 그냥 빈문자열들로 사용자가 생성될것이기 떄문에
        # 입력받은값에 대한 예외처리를 한것임.
        # 딕셔너리라 키가없으면 에러가 나니까, 겟함수를 사용해서 기본값을 지정한다.

        res_data = {}

        if not (username and password and re_password and useremail):
            res_data['error'] = '값이 누락되었습니다.'
        elif password != re_password:
            res_data['error'] = '비밀번호가 다릅니다.'
        else:

            user = User(
                username=username,
                useremail=useremail,
                password=make_password(password)  # 암호화하고나서 저장
            )

            user.save()

        return render(request, 'register.html', res_data)
        # register.html 을 렌더링 할때 그러니까 페이지 전달할떄 데이터 넘길때 res_data가 매핑이 된다이거임
        #

4.urls

from django.urls import path
from . import views
urlpatterns = [
    path('register/', views.register),
    path('login/', views.login),
    path('logout/', views.logout),
]

좋은 웹페이지 즐겨찾기