티스토리 뷰

Web/Django

[Django] CRUD_CREATE

HAN_PY 2020. 7. 10. 17:26
반응형

0. 들어가면서

먼저 일반 form을 이용해서 GET /article/new/ 으로 새글쓰기를 위한 form을 사용자에게 보여준 후에 GET /article/create/를 통해 적은 글을 DB에 저장한다. 그리고 마지막 부분에서는 ModelForm을 사용하는 방식으로 GET방식으로 form을 보여주고  POST 방식으로 form을 저장할 수 있게 views함수에서 수정을 할 것이다.

 

 

기초 CREATE

나중에는 결합해서 하나로 쓰지만, 처음에는 create.html로 가게 하는 url이 우선 필요하고,

create.html에서 form을 제출 후에 action에 적은 url을 받아 줘야하는 url이 필요하다.

 

 

urls.py

path('create/', views.create)

 

create.html

<form action="articles/create/">

  제목: <input type="text" name="title">

  내용: <input type="text" name="content">

  <input type="submit" value="작성완료">

</form>

 

=> /articles/create/?title=1&content=2

 

views.py

from .models import Article

def create(request):

  article = Article()

  article.title = request.GET.get('title')

  article.content = request.GET.get('content')

  article.save()

  return redirect('/article/')

 


 

 

저장방법에는 2가지가 있다.

1. Article.objects.create(title=값, content=값)

2.

a = Article(title=값, content=값)

a = save()

 


최종 CREATE

아래의 코드는 기본적으로 modelform을 적용한 이후의 코드이다. 아래의 코드를 적용하려면 form 부분을 공부하고 오자.

def create(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            article = form.save()
            return redirect('articles:index')
    else:
        form = ArticleForm()
    context = {
        'form' : form
    }
    return render(request, 'articles/new.html',context)

코드정리

1. GET 요청으로 들어오는 경우

2. POST로 들어와서 DB에 저장하기 위한 경우

3. POST로 들어와서 저장하려 했으나 검증을 실패한 경우. 이 경우에는 form = ArticleForm()가 아니라 form = ArticleForm(request.POST)로 보내야 관련 에러메세지도 같이 들어가진다.

 

 

def create(request):

    if request.method == 'POST':

post부분이다

    

    form = ArticleForm(request.POST)

여기서 form은 ArticleForm의 인스턴스다.

request.POST는 딕셔너리다. {'title': ~, 'content': ~}

 

        if form.is_valid():

검증. request.POST에 담긴 내용으로 판단한다.

 

            article = form.save()

위의 from이 form으로 들어온다.

save()는 ArticleForm의 메서드를 호출한거다. 큰그림으로는 article.save를 내부적으로 한다고 할 수 있지만, 우리의 의도는 ArticleForm을 save한거다

즉, form자체에 save 함수를 호출하면, DB에 저장을 하고 Article 인스턴스를 반환하게 된다. article의 인스턴스 object를 반환한다.

 

        return redirect('articles:index')

 

    else:

get 부분으로 사용자에게 비어있는 form을 보여주는 로직이다.

 

        form = ArticleForm()

 

    context = {

get과 post가 공통으로 사용하는 부분이라고 할 수 있다.

        'form' : form

 

    }

 

    return render(request, 'articles/new.html',context)

 


GET으로 들어오면 form = ArticleForm()으로 비어있는거 보내고 POST로 들어오면 post 처리하고 valid되면 return한다. 즉, POST는 form = ArticleForm(request.POST)로 적어주면된다. request.POST에는 유효한지 유효하지 않은지도 담겨있다.

+HTML 개발자 도구에서 input의 required를 지우고 실험해보면 된다.

그리고 CREATE와 UPDATE는 코드는 비슷하지만 받는 인자가 달라서 합치기는 힘들다.

 

update 같은 경우는 해당 내용도 전달해 줘야하기 때문에 article 인스턴스도 적어 줘야한다.

POST는 form = ArticleForm(request.POST, instance=article)이고 GET은 form = ArticleForm(instance=article)로 해주면 된다.

 

 

 


같은 FORM 쓰기(HTML)

CRUD완성 후

Create와 Update의 html이 form으로 비슷하다. 그래서 같이쓰자. form.html로 하나로 바꾸자.

이때 HTML의 분기를 해줘서 다른 글이 보이게 하면 된다.

 

url로 분기한다. 분기의 기준은 url_name으로 분기한다.

그리고 resolver를 쓰면 url이 아니라, url이름으로 분기가 가능하다.

 

 

https://docs.djangoproject.com/en/3.0/ref/request-response/

 

Request and response objects | Django documentation | Django

The Django Software Foundation deeply values the diversity of our developers, users, and community. We are distraught by the suffering, oppression, and systemic racism the Black community faces every day. We can no longer remain silent. In silence, we are

docs.djangoproject.com

위의 공식 문서중 HttpRequest objects를 확인해 보면

.request.path_info 는 고정된 string url로 비교를 해준다. (이거 사용해도된다)

class ResolverMatch는 url의 name을 사용하는 것인데 우리는 이걸 사용한다.

 

html 분기

{% if request.resolver_match.url_name == 'create' %}

    <h2>새글쓰기</h2>

{% else %}

    <h2>수정하기</h2>

{% endif %}

 

이때 request를 바로 쓸 수 있는 이유는 settings.py에서 TEMPLATES안의 OPTIONS 안에 contenxt_precessors 안에 보면 자동으로 context로 넘어가면서 request 쓸 수 있게 설정이 되어있다.

 

 


로그인을 해야 글이 작성되게 만들자.

우리는 회원가입 구현 시, 로그인 된 상태에서 회원가입페이지나 로그인 페이지로 못들어 오게 하려고 if request.user.is_authenticated를 사용했다. 이러한 방식처럼 함수안에 내용을 if조건문을 쓰고 else에 redirect를 넣어서도 가능하지만 우리는 아래와 같이 더 좋은 방법을 사용한다.

 

 

from django.contrib.auth.decorators import login_required

@login_required

def create(request):

    if request.method == 'POST':

        form = ArticleForm(request.POST)

        if form.is_valid():

            article = form.save()

            return redirect('articles:index')

    else:

        form = ArticleForm()

    context = {

        'form' : form

    }

    return render(request, 'articles/new.html',context)

 

@login_required정리

1. 로그인 경로로 가게한다.

2. 그 후 next 파라미터를 활용할 수 있는 url로 만들어 준다(login게시물에서 확인)

즉, 로그인이 필요한 상황에서는 반드시 활용 해 줘야한다.

 

@login_required의 추가설명

공식문서를 찾아보면 login_URL은 settings.py 내부에 default값(기본값)으로 '/accounts/login/' 이라고 설정이 되어있다. 이설정에 따라 login url이 온거다. # LOGIN_URL = '/accounts/login/' # login_required

내가 만약, '/accounts/signin/'으로 url을 설정했다면, settings.py 하단에 LOGIN_URL='/accounts/signin/'이라고 지정을 해주면 된다.

반응형

'Web > Django' 카테고리의 다른 글

[Django] CRUD_UPDATE  (0) 2020.07.14
[Django] CRUD_READ_목록페이지 구현  (0) 2020.07.12
[Django] URL 변수화  (0) 2020.07.09
[Django] HTTP+ GET과 POST  (0) 2020.07.08
[Django] 프로필 이미지 구현_gravatar (python코드의 확장)  (0) 2020.07.08
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함