ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Django Form Class
    Django 2024. 8. 17. 03:13

    Django Form Class

     

    일부 반복되는 작업 및 코드를 줄일 수 있는 기능으로 Model과 흡사한 형식으로 진행된다.

    폼에 입력받고 싶은 데이터 형식을 정의한 후, 그렇게 정의해놓은 걸 기준으로 자동으로 폼이 생성되게 해준다.

     

     

    1) Form 선언하기

     

    articles/ forms.py 

    from django import forms
    
    class ArticleForm(forms.Form):
        title = forms.CharField(max_length=50)
        content = forms.CharField() # max_lenth를 지정하지 않으면 길이 제한 없게 입력받는 형식이 됨

    • Model과 비슷하게 이 Form에서 입력받고자 하는 데이터에 대한 내용을 작성한다.
    • 형식이나 속성도 일부 Model과 비슷하다.

     

    2) Form 적용하기

    ...
    {{ form.as_p }}
    ...

     

    현재 new.html기존의 form이 있다. 

     

    여기서 우리가 위에서 지정한 제목 title이랑 내용 content 부분을 지워주고

     

     

    얘로 바꿔주면 됨  →  {{ forms.as_p }} 

    신기🫢

     

    forms는 context로 내용을 받아온거기 때문에 view로 가서 받아올 수 있게 작성해줘야 한다.

     

     

    views.py 열어서

    우리가 만든 클래스 ArticleForm class를 뷰에서 만들어주면 된다.

     

    forms에서 ArticleForm 임포트 해주고

    from .forms import ArticleForm

     

    이렇게 forms 가져오고

    context에 담아서 인자로 넘겨주면 된다.

     

     

    서버실행 해보면 잘 나오는 걸 볼 수 있다. 왜 이렇게 감동이지..🥹 ㅎㅎ

    근데...🤔 

     

    이럴 때 쓰는게

     

    Form Widget

     

    • 웹 페이지에서 Form Input 요소가 어떻게 렌더링 되어서 보여질지 정의한다.
    • Form Fields에 할당해서 사용한다.

    *공식문서

     

    articles/forms.py (text field)

    from django import forms
    
    class CommentForm(forms.Form):
        name = forms.CharField()
        url = forms.URLField()
        comment = forms.CharField(widget=forms.Textarea)

    from django import forms
    
    class ArticleForm(forms.Form):
        # 앞은 데이터베이스에 저장될 값, 뒤는 사용자에게 보여질 값
        GENRE_CHOICES = [
            ("technology", "Technology"),
            ("life", "Life"),
            ("hobby", "Hobby"),
        ]
    
        title = forms.CharField(max_length=10)
        content = forms.CharField(widget=forms.Textarea)
        genre = forms.ChoiceField(choices=GENRE_CHOICES)

     


     

    Django Model Form Class

     

    알아서 Model을 참조해 Form을 만들어주는 ModelForm Class

     

    폼 클래스와 마찬가지로 articles/forms.py에서 만들어주면 된다.

     

    폼 클래스에서는 (forms.Form)을 상속받았다면, 얘는 (forms.ModelForm)을 상속받는다.

    from django import forms
    
    from articles.models import Article
    
    class ArticleForm(forms.ModelForm):
        class Meta:
            model = Article
            fields = "__all__"
            # exclude = ["title"] 제외하고자 하는 옵션

     

     

     

    어떤 Model을 참조해야 되는지 알려주는 코드 : Meta class 

    class Meta:

     

     

    이 model에 있는 모든 field에 대해서 입력을 받겠다는 의미 : "__all__"

    fields = "__all__"

     

     

     

    서버 실행 해보면

     

    에러 없이 한번에 되니 세상을 가진 것 같다...ㅎㅎ 

     


     

    view에서 Django Model Form 사용하기

    게시글이 작성됐다면, 폼에는 반드시 데이터가 채워져서 저장되었을거다.

     

    기존에 작성했던 코드↓ 

    def create(request):
    	title = request.POST.get("title")
    	content = request.POST.get("content")
    	article = Article.objects.create(title=title, content=content)
    	return redirect("article_detail", article.pk)

     

     

    즉, Form에 데이터가 채워져있는 상태로 요청을 받도록 코드를 수정해보자.

     

    → articles/views.py 

    ...
    def create(request):
      form = ArticleForm(request.POST) # form에 request.POST에 있는 데이터 채워
      if form.is_valid(): # form 형식에 맞으면
          article = form.save() # 저장하고 해당 객체 반환 
          return redirect("article_detail", article.id)
      return redirect("new")
    ...

     

     

    이렇게 수정해주면, 서버 실행해서 확인해봐도 데이터가 채워져야만 저장이 되는 걸 확인할 수 있다.

     

     

    🤔 조금 더 생각해보자

     

    현재 new 함수create 함수가 많이 흡사하니까

    def new(request):
        form = ArticleForm()
        context = {
            "form": form,
        }
        return render(request, "new.html", context)
    

     

    ⇒ 그냥 create 함수 하나로 처리해보자.

    • request가 GET 방식으로 들어오면 비어있는 Form 렌더링해서 주고, POST 방식으로 들어오면 데이터 채워서 보낸거니까 새로운 article을 생성하면 된다.

     

    new - create 수정하기

     

    • articles/views.py 로 들어와서 create 코드 수정
    def create(request):
      if request.method == "POST":
          form = ArticleForm(request.POST)
          if form.is_valid():
              article = form.save()
              return redirect("article_detail", article.id)
      else:
          form = ArticleForm()
    
      context = {"form": form}
      return render(request, "create.html", context)

     

     

    • 이제 new 함수필요 없어졌으니까 지워주고, urls.py 들어가서 path도 지워준다.
    • new.html을 create.html로 변경해준다.
    {% extends "base.html" %}
    
    
    {% block content %}
    <h1>New Article</h1>
    
    <form action="{% url 'create' %}" method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">저장</button>
    </form>
    {% endblock content %}

     

     

    • articles.html

     

    {% extends 'base.html' %}
    
    {% block content %}
    <h1>Articles</h1>
    <a href="{% url 'create' %}">새 글 작성하기</a> # 'new'를 'create'로 변경
    {% for article in articles %}
         <a href="{% url 'article_detail' article.pk %}">
            <p>[ {{ article.pk }} ] {{ article.title }}</p>
         </a>
        
    {% endfor %}
    
    {% endblock content %}

     

     

     

    edit - update

     

    edit과 update 얘네도 하나로 합쳐주자.

     

    로직을 살펴보자 🤔

     

    update

    • 일단, get으로 들어오든 post로 들어오든 조회해야 한다.
    • 만약, request.method가 POST방식이면, POST로 넘어온 데이터로 새로운 Article을 만들건데, 원래의 article에 업데이트 해야해.
    • 만약에, 이 폼에 채워진 데이터가 유효하다면 저장해. article = form.save
    • 저장한 후에는 article_detail(게시글 상세페이지)로 리다이렉트

    edit

    • edit은 게시글을 수정해주는 것이기 때문에, 폼이 비어있으면 안 된다. 채워져있는 폼을 수정해주는 거다. 
    • 이전에 작성했던 데이터는 article 개체에 들어있다. article 개체를 form에 넣는게 instance=article이므로 
    form = ArticleForm(instance=article)
    • ↑ 이렇게 하면 이 article에 들어있는 title과 content를 빼서 form에 채운 상태로 작성된다.
    • 이렇게 데이터를 채워서 모델 폼을 만들어 놓고나서, context 만들어서 렌더링
    def update(request, pk):
        article = Article.objects.get(pk=pk)
        if request.method == "POST":
            form = ArticleForm(request.POST, instance=article)
            if form.is_valid():
                article = form.save()
                return redirect("article_detail", article.pk)
        else:
            form = ArticleForm(instance=article)
        context = {
            "form": form,
            "article": article,
        }
        return render(request, "update.html", context)

     

    마찬가지로 이제 edit 필요없음

    뷰에서 edit 함수 지우고, urls에서도 지워주고, 코드 확인해서 그 외 edit 이 쓰이고 있으면 다 지워주면 됨.

     

    edit.html 도 update.html 로 바꿔주고 코드도 수정

    {% extends "base.html" %}
    
    {% block content %}
    <h1>Update Article</h1>
    
    <form action="{% url 'update' article.pk %}" method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">수정</button>
    </form>
    
    <a href="{% url 'article_detail' article.pk %}">이전으로</a>
    {% endblock content %}

     

     

    잘 된다. ㅎㅎ 이제 서버 실행했을 때 에러나면 수정 바로잡는 법도 조금 익숙해진 것 같다😊

     

     

     

    'Django' 카테고리의 다른 글

    Django 회원기능 구현하기  (0) 2024.08.18
    Django Auth, Login & Logout  (4) 2024.08.17
    Django Model, Migration, ORM, Database API  (0) 2024.08.16
    Django HTTP Form  (0) 2024.08.14
    Django Template System (DTL 문법, 템플릿 상속)  (0) 2024.08.13
Designed by Tistory.