본문 바로가기

Python_WEB/Tweetme

[Django]Tweet Create Form

반응형

CodingEntrepreneurs Django 강의 정리

Django 폼 처리 과정>

https://developer.mozilla.org/

 

  1. 사용자가 처음으로 폼을 요청할 때 기본 폼을 보여준다.
    • 폼은 비어있는 필드가 있을 수 있다 (예를 들면, 새로운 책을 등록할 경우) 아니면 초기값으로 채워진 필드가 있을 수도 있다. ( 예를 들면, 기존의 책을 수정하거나, 흔히 사용하는 초기값이 있을경우)
    • 이 시점의 폼은 (초기값이 있긴해도) 유저가 입력한 값에 연관되지 않았기에  unbound 상태라고 불린다.
  2. 제출 요청으로 부터 데이타를 수집하고 그것을 폼에 결합한다.
    • 데이타를 폼에 결합(binding) 한다는 것은 사용자 입력 데이타와 유효성을 위반한 경우의 에러메시지가 폼을 재표시할 필요가 있을 때 준비되었다는 의미이다.
  3. 데이타를 다듬어서 유효성을 검증한다.
    • 데이타를 다듬는다는 것은 사용자 입력을 정화(sanitisation) 하고 (예를 들면, 잠재적으로 악의적인 콘덴츠를 서버로 보낼수도 있는 유효하지 않은 문자를 제거하는 것)  python에서 사용하는 타입의 데이타로 변환하는 것이다.
    • 유효성검증은 입력된 값이 해당 필드에 적절한 값인지 검사한다. (예를 들면, 데이타가 허용된 범위에 있는 값인지, 너무 짧거나 길지 않은지 등등) 
  4. 입력된 어떤 데이타가 유효하지 않다면, 폼을 다시 표시하는데 이번에는 초기값이 아니라 유저가 입력한 데이타와 문제가 있는 필드의 에러 메시지와 함께 표시한다.
  5. 입력된 모든 데이타가 유효하다면, 요청된 동작을 수행한다. (예를 들면, 데이타를 저장하거나, 이메일을 보내거나, 검색결과를 반환하거나, 파일을 업로딩하는 작업 등등)
  6. 일단 모든 작업이 완료되었다면, 사용자를 새로운 페이지로 보낸다.

폼 필드 공통 인자>

  • required: True 로 설정되면, 필드를 빈칸으로 두거나 None 값을 줄 수 없게된다. 보통필드는 required는 True로 기본 설정되므로, 폼에서 빈 칸을 허용하기 위해서는required=False 로 설정해야 한다. 
  • label: HTML에서 필드를 렌더링할때 사용하는 레이블이다. label 이 지정되지 않으면,  Django는 필드 이름에서 첫번째 문자를 대문자로, 밑줄을 공백으로 변형한 레이블을 새로 생성할 것이다. (예를 들면, renewal_date  --> Renewal date).
  • label_suffix: 기본적으로, 콜론(:)이 레이블 다음에 표시된다. (예를 들면, Renewal date:). 이 인자는 다른 문자(들)를 포함한 접미사를 지정할 수 있도록 해준다.
  • initial: 폼이 나타날 때 해당 필드의 초기 값.
  • widget: 사용할 디스플레이 위젯.
  • help_text (위의 예에서 봤듯이): 필드 사용법을 보여주는 추가적인 문구.
  • error_messages: 해당 필드의 에러 메시지 목록. 필요하면 문구를 수정할 수 있다.
  • validators: 해당 필드가 유효한 값을 가질 때 호출되는 함수의 목록.
  • localize: 폼 데이타 입력의 현지화(localisation)를 허용함
  • disabled: 이 옵션이 True 일때 해당 필드를 볼 수는 있지만 편집이 안됨. 기본 값은 False.

 

{% csrf_token %}>

1. CSRF보호 기능

 

https://docs.djangoproject.com/ko/3.0/ref/csrf/

 

Cross Site Request Forgery protection | Django 문서 | 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

 

forms.py>

# tweets/forms.py

from django import forms

from .models import Tweet

MAX_TWEET_LENGTH = 240


class TweetForm(forms.ModelForm):
    class Meta:
        model = Tweet
        fields = ["content"]

    def clean_content(self):
        content = self.cleaned_data.get("content")
        if len(content) > MAX_TWEET_LENGTH:
            raise forms.ValidationError("This tweet is too long")
        return content

 

views.py>

# tweets/views.py

import random
from django.http import HttpResponse, Http404, JsonResponse
from django.shortcuts import render

from .forms import TweetForm
from .models import Tweet

# Create your views here.
def home_view(request, *args, **kwargs):
    return render(request, "pages/home.html", context={}, status=200)


def tweet_create_view(request, *args, **kwargs):
    form = TweetForm(request.POST or None)
    if form.is_valid():
        obj = form.save(commit=False)
        # do other form related logic
        obj.save()
        form = TweetForm()
    return render(request, "components/form.html", context={"form": form})


def tweet_list_view(request, *args, **kwargs):
    """
    REST API VIEW
    Consume by JavaScript or Swift or Java/ios/Andriod
    return json data
    """
    qs = Tweet.objects.all()
    tweets_list = [
        {"id": x.id, "content": x.content, "likes": random.randint(0, 1000)} for x in qs
    ]
    data = {"isUser": False, "response": tweets_list}
    return JsonResponse(data)


def tweet_detail_view(request, tweet_id, *args, **kwargs):
    """
    REST API VIEW
    Consume by JavaScript or Swift or Java/ios/Andriod
    return json data
    """
    data = {
        "id": tweet_id,
    }
    status = 200

    try:
        obj = Tweet.objects.get(id=tweet_id)
        data["content"] = obj.content
    except:
        data["message"] = "Not Found"
        status = 404

    return JsonResponse(
        data, status=status
    )  # json.dumps content_type='application/json'

 

form.html>

<!-- templates/components/form.html -->

<form method="POST">{% csrf_token %}
    {{ form.as_p}}
    <button type="submit" class="btn btn-secondary">Save</button>
</form>

 

urls.py>

# tweetme2/urls.py

"""tweetme2 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path  # url

from tweets.views import (
    home_view,
    tweet_detail_view,
    tweet_list_view,
    tweet_create_view,
)

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", home_view),
    path("create-tweet/", tweet_create_view),
    path("tweets/", tweet_list_view),
    path("tweets/<int:tweet_id>", tweet_detail_view),
]

 

결과물>

반응형