보통은 함수형으로 작성을 먼저 할 텐데... 뭔가 순서가 바뀐 느낌.
아무튼 이번에는 CRUD를 함수형 view를 사용해 구현해보자.
1. url 수정
viw의 이름은 다 똑같이 쓸 테지만, 클래스형 뷰에서 함수형 뷰로 바뀌었으니 url수정이 필요하다!
urls.py
사실 수정이랄 것도 없다... .as_view()만 다 빼주면 된다.
2. R
제일 먼저(쉬운) R.
게시글 전체를 띄워주는 기능 대신, 자신이 작성한 게시글만 띄워주도록 해보자.
해당 함수는 PostChangeLV, html명은 post_change_list.html !
views.py
이 정도만 돼도 할만하다!
Post라는 모델의 모든 것을 불러왔고, 이를 context에 담아 post_change_list.html에 전달!
post_change_list.html
현재 사용자가 게시글의 작성자여야만 해당 게시글을 수정할 수 있어야 한다.
따라서 for문을 통해 게시글 전체를 받아온 후,
if문을 써서 게시글 작성자(item.owner) == 현재 사용자(request.user) 일 경우,
자신이 작성한 글의 제목을 볼 수 있도록 했다.
그 밑에는 해당 게시글을 수정, 삭제할 수 있는 Update와 Delete 버튼이 뜨게끔!
그럼 이렇게 user가 lee일 경우, owner가 lee인 게시글만 나타난다.
3. C
다음은 새로운 게시글을 작성할 수 있는 기능.
CreateView를 사용했을 때는 모델만 정해주면 해당 모델을 생성할 수 있는 form을 자동으로 html상에 넘겨줬다.
하지만 함수형이므로 그런 거 없다!
즉 Post라는 모델을 생성할 수 있는 틀, form을 직접 만들어줘야 한다는 말씀.
form.py
이전 댓글을 만들었을 때와 비슷하다.
위에 Post 모델을 import 해주고, 작성받고자 하는 모델의 fields들을 적어주면 된다.
views.py
대망의 views!
클래스형 뷰에서는 자동으로 GET 요청이면 대기, POST 요청이면 view를 작동시켰다.
역시 함수형이므로 그런 거 없다!
request의 method가 POST일 경우, 즉 form을 통해 POST 요청을 보낸 경우!
PostCreateForm(request.POST) -> 즉 우리의 PostCreateForm에 해당 POST 요청의 데이터를 담아준다.
이를 form이라는 이름으로 붙이기!
if문을 통해 form이 유효하면 -> .save()로 저장!
그런데 저장하기 전, 각 게시글마다 owner라는 필드가 존재한다.
이 owner는? 당연히 현재 글을 작성한 사람이다! 즉 작성자에게 입력받을 필요 없이 자동으로 생성되야한다!
이를 위해 클래스형 뷰처럼 모델 객체(instance)를 생성해 form의 내용을 오버 라이딩!
여기서 .save() 메소드는 입력된 데이터의 Primary Key의 값을 판단하여 내용을 삽입 및 수정한다.
즉 Primary Key를 바탕으로 DB에 존재하는 값일 경우 수정을, 신규 값일 경우에는 삽입을 수행!
그렇기 때문에 이후 Update기능에서도 .save()를 사용하는 것!
저장 후에는 게시글들이 모여있는 post_list.html로 보내주기 위해 index url을 redirect 시켰다.
잘 쳤다고 생각했지만 어김없이 에러!
is_valid() missing 1 required positonal argument : 'self' 라는데...
self라는 필수 인자가 빠졌단다. 이 경우 유력한 용의자들은 () 가 붙어야 하는 녀석들.
즉 .is_valid() , .save() , PostCreateForm() 등이 되겠다.
post_form.html
크게 달라진 건 없다!
Add 버튼이 누르면, 이렇게 우리가 설정해 준 form이 잘 뜨는 걸 볼 수 있다.
4. U
요 페이지에서 Update버튼을 누르면 해당 게시글의 내용을 수정할 수 있도록!
views.py
낯익은 코드!
맞다. C를 담당하는 CreatePostView와 거의 흡사하다.
어쩌면 당연하다! 게시글을 수정하는 것도 결국 새로운 게시글을 하나 작성하는 것과 유사한 개념이니까.
하지만 (당연히) 이렇게 쓰면 문제가 있다.
으악. 우린 분명 해당 게시글을 수정하고 싶은데... 아예 새로운 글을 작성하는 게 돼버렸다.
수정을 위해서는? 존재하는 게시글의 내용을 그대로 가져와야 한다!
다시 view를 작성하러 가보자.
아까와 크게 달라 보이지는 않지만... 크게 다르다.
우선 각 게시글들을 구별하기 위해 post_pk란 녀석을 받아왔다는 점.
요 post_pk는? 아까 update가 있던 페이지에서 클릭했을 때 보내준, 각 게시글의 id!
즉 get_object_or_404(Post, pk=post_pk)를 통해,
Post라는 모델에서 고유의 값(pk)이 url에서 보내준 post_pk와 같은 녀석을 가지고 온 것!
또한 form=PostCreateForm(request.POST, instance=my_post)를 통해,
입력받을 form이 각 게시물 즉 my_post임을 알려줬다!
쨔잔. 이제는 게시글의 기존 내용이 잘 나온다.
5. D
delete 역시 update처럼 삭제하고 싶은 게시글을 직접 들고 와야 한다!
views.py
.delete()는? 그냥 삭제해주는 함수!
Delete버튼을 누르면 삭제가 잘 되는 걸 볼 수 있다.
아차차. 그런데 해당 CRUD 기능은 모두 로그인 한 사용자만 이용할 수 있어야 한다.
함수형 뷰를 사용했기 때문에...
@login_required를 붙여주면 해당 함수들은 로그인을 해야 작동한다!
로그인하지 않았을 때는 로그인 페이지로 이동시켜준다.
확실히 클래스형 뷰보다 작성해야 하는 코드가 많다!
하지만 자신이 확실하게 원하는 대로 작동시킬 수 있다는 부분,
강제적인 html이나 오버 라이딩 요소가 없다는 점 등은 분명한 강점.
그러므로...? 둘 다 잘할 줄 알아야 한다! 화이팅.
'source-code > Django' 카테고리의 다른 글
Blogs App _ 동적 페이지 만들기 (0) | 2021.01.08 |
---|---|
Blogs App _ 인증 기능 with 사용자 지정 (0) | 2021.01.07 |
Blogs App _ CRUD (0) | 2021.01.05 |
Blogs App _ 인증 기능 (0) | 2021.01.05 |
Blogs App _ 검색 기능 (0) | 2021.01.04 |