초보 개발자

django sparta 강의 정리 및 의문점 본문

AI 웹개발 트랙 - 내배캠/6주차

django sparta 강의 정리 및 의문점

taehyeki 2022. 1. 19. 19:10

 

auto_now , auto_now_add의 차이

#user/models.py
from django.db import models


# Create your models here.
class UserModel(models.Model):
    class Meta:
        db_table = "my_user"

    username = models.CharField(max_length=20, null=False)
    password = models.CharField(max_length=256, null=False)
    bio = models.CharField(max_length=256, default='')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

 

create_at과 updated_at에서 auto_now와 auto_now_add라고 적혀있는데 이게 무슨 차인지 알아보았다.

 

  • 수정일자 : auto_now=True 사용
    auto_now=True 는 django model 이 save 될 때마다 현재날짜(date.today()) 로 갱신된다.

 

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

 

생성일자에서 수정하면 오류가 날 수도 있다는데 이건 나중에 다시 적어야 겠다.

 

------------------------------

 

중간에 mirgration을 하면 기존 정보들의 값도 바뀔까? 

 

위의 model에서 bio를 bioo로 바꾼 뒤 makemigrations와 migrate를 하면 잘 수정이된다.

그럼 데이터가 있는 상태에서 바꾼다면 기존에 있던 건 bio일까 bioo로 바뀔까?

 

실험해보았더니 기존의 것도 bioo로 잘 바뀐 것을 볼 수 있다.

-------------------------------

관리자 페이지에서 모델을 볼 수 있도록 admin에 추가하는 방법

 

관리자 페이지에 

 

model을 사용할 수 있도록 하려면 app내의 admin에서

아래와 같이 작성해야 보인다.

from django.contrib import admin
from .models import UserModel
# Register your models here.


admin.site.register(UserModel)

 

foreign key로 가져오는 방법이다.

# tweet/models.py
from django.db import models
from user.models import UserModel


# Create your models here.
class TweetModel(models.Model):
    class Meta:
        db_table = "tweet"

    author = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    content = models.CharField(max_length=256)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

user.models 유저앱의 모델을 가져와서 이름이 UserModel인 애를 가져온것이다.

author을 보면 foreinkey인데 이건 다른 데이터베이스에서 내용을 가져오겠다라는 것이다.

 

---------------------------------

 

url 설정방법 .은 언제 쓰고 언제 안쓰는걸까??

url설정방법 user app에 urls.py파일을 만들어주고

user.urls.

. 의 역할은 아직 잘 모르겠다, 있을 때도 없을 때도 있어가지고..

django.urls 의 path를 임포트해와서

urlpatterns = [ path('url명',뷰 함수, 이름)] 이렇게 적으면 url이 생성이 된다.

view에는 url로 들어오면 적절한 html을 렌더링해주는 함수들이 있다.

이렇게만 해주면 django가 아직 인식을 못한다. 한가지 더 해주어야 되는데

프로젝트의 urls에 가서 아래와 같이 include를 사용해서

path('url', include('app의urls' )) 이렇게 설정해주자

url에 예를들어 user/라고 적으면 기본값이 user가 된다.  user.urls에서 sign-up과 같이 적어주었는데 

user/sign-up과 같은 url로 변하게 되는 것이다.

config.urls

include가 알아서 앱의 urls를 인식해오는게 신기하다.

 

-----------------------

form태그에서 보낸 정보를 서버에서 읽기

 

if request.method == 'POST'라면 아래와 같이 코드가 이어지는데 

username의 값을 가져와라 만약 username이 없으면 None이 들어온다는 뜻이다.

 

 

--------------------

 

form에서 action보낼 때 뒤에 /슬래시 꼭 붙여주기

 

 

form action form 보낼 때 sign-up 이라고 보내면 현재 url + sign-up이라고 보내지기에

/sign-up 앞에 /를 붙여주어야 하고 또 이렇게만 보내면 런타임 오류가난다 따라서

/sign-up/ 이렇게 보내주어야 한다

그리고 {% csrf-token %} 이걸 안적어주면 장고에서 form문을 안받는다고한다. 보안상의 이유라고한다.

-----------------

 

baseurl에는 상위 경로를 안적어 주어도 되는건가??

 

이건 template/user/sign-up.html 이다

근데 base.html은 template/base.html이다

저기서 상위 경로로 안적어줘야 한다고 생각했는데

저렇게만 적어도 실행이 잘되긴 된다.

 

----------------------

 

form 으로 정보를 전송할 때 name을 꼭 달아주어야함 id는 상관 x

 

form으로 전송할 경우는 반드시 name="변수명" id아님

 

--------------------------

 

유저를 받아올 때 get와 filter의 차이

 

orm에서 값이 있는지 없는지 확인할려면 filter를 적어주어야 빈배열 반환한다.

get은 값이 있으면 반환하고 없다면 에러를 반환한다. 따라서 아이디 유무를 판별할 때 get을쓰면오류남

 

---------------------------

 

장고 auth_user의 기능을 받아와서 기능 보강 한 후 우리만의 user만들기

UserModel을 만들 때 models.Model쓴 것이 상속받아왔기 때문이었다.

그럼 저 안에 있는 기능들을 쓸 수 있을 것이다.

 

AbstractUser을 import 해와서 UserModel에 넣어주었다,

AbstractUser은 장고가 기본적으로 제공하는 auth_user랑 연동되는 클래스이다.

장고의 기본 모델을 사용할 것인데 우리만의 기능(bio)을 추가할 것이 있을 때 이렇게 사용한다.

 

이렇게 수정해주고 makemirations migrate를 해주는 것 말고도 해줘야 할 것이 있다고 한다.

settings에 들어가서 아래의 내용을 적어주자

우리는 장고의 기본 모델에 다른 기능을 추가했고 그걸 유저모델로 사용하겠다는 것을 알려주는 것이다.

 

 makemirations migrate해주고 데이터베이스를 보면 auth_user의 구조를 my_user가 사용하는 것을 볼 수 있다.

이제 장고는 이걸 기본 모델로 인식한다.

더보기

get_user_model()을 실행시키면 현재 등록된 User의 정보가 나오는데 기본적으로는 아래와 같다.

<class 'django.contrib.auth.models.User'>

하지만 settings에서 설정을 바꾸면

<class 'uesr.models.UserModel'>로 인식이 된다.

 

이를 확인하는 방법은 아래와 같다.

설치 > pip install django-extensions

settings.py에 app추가 'django_extensions'

app에 추가 안해주면 실행이 안됨

shell_plus 실행 > python manage.py shell_plus

 

shell_plus 실행 >>> get_user_model()을 해주면 확인할 수 있다.

 

디폴트 값은 아래와 같다.

AUTH_USER_MODEL = 'auth.User'

따라서 get_user_model()을 실행시키면 현재 우리가 바꿔준 user.models.UserModel로 인식이 된다.

 

데이터베이스에서 정보를 가져올때는 get_user_model을사용하고

데이터를 추가할 때는 UserModel을 사용하시던데 별다른 설명이 없었다.

 

주석처리 된 문장으로 해보았더니 똑같이 데이터베이스에 저장이 되었다.

두 방법에는 무슨 차이가 있는걸까?

 

------------------------------------------------------------------

 

로그인에서 받아온 정보를 장고가 데이터 베이스에서 확인하는 절차

 

앞서 회원가입을 할 때 장고가 알아서 password를 해쉬화 해주었다. 따라서 기존의 코드로는 로그인할 수가 없다.

이 부분도 처리를 해주어야 하는데

먼저 from django.contrib import auth

me = auth.authenticate(request, username=username, password = password)를 통해서 확인이 가능하다. 이건 암호화된 비밀번호와 현재 입력된 비밀번호가 일치하는지를 확인해주는 기능을한다. 따라서  조건이 일치한다면

일치하는 사용자를 반환한다

if not me 이렇게 분기문을 바꿔주면 된다.

그리고 me를 사용해서 login 까지 시켜주면 된다.

 

login이 어떤 기능을 수행해주는걸까?? 세션? 쿠키?

-----------------------------------------

로그인 유무에 따른 페이지 이동 및 템플릿 정보표시

 

request.user.is_authenticated를 사용하면

유저가 로그인 되어있는지 확인이 가능하다. 로그인 되어있으면 /tweet으로 redirect를 시키고

아니라면 /sign-in으로 로그인 시키러 보낸다.

 

-----------------------------------------------

 

로그인 유무에 따른 페이지 이동 및 템플릿 정보표시

 

 

페이지를 render할 때 따로 user정보를 보내주지 않았는데 template에서 알아서 인식을한다. 신기하다

session에서 뭔가 해주는건가?? 

따라서 nav에서도 user가 로그인이 되어있는지에 따라 다른 화면을 보여줄 수도 있다.

다만 if not user라고 했을 때는 작동하지 않았다. user.is_authenticated라고 적어주어야 한다.

user가 없을때에도 None이 아닌 빈값을 반환하는거 같다??

/tweet이라는 글을 적는 페이지에도 로그인이 되어야지만 들어올 수 있도록 해주었다.

근데 여기서 드는 의문점. 모든 view에 이렇게 일일이 해주어야하나? 사전에 미리 미들웨어로막을 수 있는 기능은 없을까?

from django.contrib.auth.decorator import login_required 라는 데코레이터가 있다.

이건 로그인이 되어있어야지만 기능을 수행한다.

반대로 로그인이 되어있지 않아야만 수행하는 것은 없을까??

그건 일일이 user.is_authenticated로 확인해야하는건가??

logout은 auth의 logout이 하나로 다 해결이 되는 것 같다. 세션 저장소에서 기록을 확인하고 지워주는 역할 까지 다해준다. 그리고 쿠키까지 삭제가 된다.

 

Model 데이터 정렬해서 불러오기

 

Model.objects.all().order_by('-filed')

 

강의 내용에선 TweetModel.objects.all().order_by('-crated_at')

-을 적어주면 내림차순으로 가져온다.

 

Model 데이터 삭제하기, url변수, 글작성자 로그인유저 비교

먼저 데코레이터 login_required를 통해서 로그인이 되어있는 사용자만 지워주려고 하였다.

request옆 id는 뭐냐면 저걸 지우는 url에 <>로 감싸주면 그 값이 변수로 들어온다. 따라서 tweet_delete에서 사용할 수 있다. 근데 int는 생략해도 잘 돌아가는 걸로 보아서 필수는 아닌 것 같다.

먼저 받아온 id로 트윗의 글번호와 일치하는 녀석을 찾아온다. 그리고 이게 젤 중요한 것 같은데, 강의에서는 단순히 삭제버튼이 현재 유저와 일치하지 않으면 보이지 않게만 처리해두었다. 글 번호를 알고있는 유저라면 마음대로 글을 삭제할 수 있는 구조이다. 따라서 현재 접속해있는 유저의 정보 request.user의 id값과 글을 작성한 유저의 정보의 tweet.author.id ( author엔 모델 전체가 들어가기때문에 여기서 자료를 긁어올 수 있다. ) 를 비교하여 일치하지않으면 삭제를 안시켜주는 방식으로 해봤다.

 

삭제하는 기능은 찾아온 녀석.delete()이다.

 

Model 데이터 정렬해서 불러오기2

id에는 tweet의 id가 들어가있다. 따라서 해당 tweet을 찾은 뒤

해당 tweet에 달린 comment를 찾기 위해서 filter를 사옹해주었다. 여기서 tweet.id로 적었다가 안되가지고

tweet_id로 적으니 잘 되었다. 아래에서

찾아온 comment에서 id에 접근할 때에는 

comment.tweet.id로 접근해도 잘되었는데

 

comment를 찾기 위한 과정에서는 tweet_id로 해야하는 것 같다. 

애초에 comment의 tweet에 tweet의 id를 넣은 것이 아니라 tweet 통째로 넣어버렸지만

sql에서는 그걸 tweet_id로 해석하는것 인가? 이 부분이 좀 헷갈리지만

 

여기서 확실히 해둘 수 있는것은 찾아온 데이터에는 comment.tweet.id를 할 수 있지만

comment를 찾기 위한 fliter에는 tweet_id=id라고 적어야 한다 tweet.id = id x

 

request.user 와 Usermodel에서 가져온 정보는 다르다.

물론 정보를 가져올 수는 있지만 같다고는 생각하면 안될 것 같다.

예를들어서 request.user.follow(필드명).add으로 접근하면 안되는데

Usermodel.objects.get(id=me.id).follow(필드명).add로 접근하면 된다.

 

Taggit 

 

글에 태그 기능을 추가해주기 위해서 아래의 모듈을 설치하였다.

pip install git+https://github.com/jazzband/django-taggit.git@master
pip install django-taggit-templatetags2

 

그리고 settings.py에 app에 아래처럼 추가해주자 초록글씨는 앱추가!

 

TweetModel

tweetmodel안에 위의 내용을 넣어두자 blank=True라는 것은 값이 없어도 된다 라는 뜻이다 저게 없다면 무조건 값이 채워져야 한다. 그다음 makemigrations migrate를 해주자

'AI 웹개발 트랙 - 내배캠 > 6주차' 카테고리의 다른 글

6주차 WIL  (0) 2022.01.22
django views class  (0) 2022.01.21
AWS EC2 배포 및 가비아 연결  (0) 2022.01.21
django {% url %}  (0) 2022.01.21
many-to-many  (0) 2022.01.21