240415 Django Form 활용

송용진·2024년 4월 15일

Django 폼 활용

#config/urls.py
from django.urls import path
from django.contrib import admin,include

urlpatterns= [
    path('admin/',admin.site.urls),
    path("c/",include("chinese.urls")),
]
# chinese/urls.py
from django.urls import path
from . import views

urlpatterns=[
    path("",views.index),
]
<!-- chinese/index.html -->
<h1>Index</h1>
<form action="" method="post">
    {%csrf_token%}
    <label for ="username">이름:</label>
    <input type="text" id="username" class="" name="username">
    <input type="submit" value="제출">
</form>
#chinese/views.py
from django.shortcuts import render

def index(request):
    return render(request=request,template_name='chinese/index.html')
#chinese/models.py
from django.db import models

class Food(models.Model):
    name = models.CharField(max_length=20)
    description = models.TextField(default="")
<!-- index.html -->
<h1>Lion 중화요리</h1>
<form>
    <label for = "bio">소개:</label>
    <textarea id="bio" name="bio" rows="4" cols="50"></textarea>
    <input type = "submit" value="제출">
</form>
<form action="" method="post">
    {% csrf_token %}
    <label for = "foodname" >음식이름:</label>
    <input type="text" id="username" class="" name="name">
    <input type="submit" value="제출">
</form>
#chinese/views.py
from .models import Food
from django.shortcuts import render
def index(request):
    if request.method == 'POST':
        Food.objects.create(name=request.POST.get('name')).save() 
        # get 메소드는 딕셔너리에서 키에 해당하는 값을 가져오는 메소드
    elif request.method == 'GET':
        pass
    return render(request=request,template_name='chinese/index.html')

request.POST.get('name') vs request.POST['name']

request.POST.get('name')

get 메소드는 지정된 키('name')가 존재하지 않을 경우 None을 반환

이는 키가 없어도 KeyError가 발생하지 않게 하여 코드의 안정성을 높여줌

request.POST['name']

대괄호를 사용하여 'name' 키에 직접 접근

이 방식은 키가 POST 데이터에 존재할 것이라고 확신할 때 사용됨

만약 'name' 키가 POST 데이터에 존재하지 않으면 KeyError가 발생

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

class Category(models.Model):
    name = models.CharField(max_length=20)

class Food(models.Model):
    category = models.ForeignKey(Category,on_delete=models.CASCADE)
    name = models.CharField(max_length=20)
    price = models.IntegerField()
    description = models.TextField()
    
 
# chinese/views.py
from django.shortcuts import render
from .models import Category,Food

def index(request):
    # get(그냥 주소 입력해서 오면) -> 페이지만 보여주고    
    if request.method == 'GET':
        return render(request=request,template_name='chinese/index.html')
        # 그냥 페이지만 보여주면 됨

    # post -> DB에 입력하는 과정을 넣자
    elif request.method == 'POST':
        category = Category.objects.get(name=request.POST['category'])
        food_name = request.POST['lion_name']
        food_price = request.POST['price']
        food_description = request.POST['description']
        food_takeout = request.POST['takeout']

        Food.objects.create(category=category,name=food_name,price=food_price,description=food_description)
        return render(request=request,template_name='chinese/index.html')
        # 그냥 페이지만 보여주면 됨 
        
        # Food.object.create(name='라떼')
        # request.POST['lion_name']
<!-- chinese/templates/chinese/index.html -->
<h1>Lion 중화요리</h1>
<form action="" method="post">
  {% csrf_token %}
  <!-- 드롭다운 메뉴 -->
  <div>
    <label for = "category">카테고리 선택:</label>
    <select name="category">
      <option value="면류">면류</option>
      <option value="식사류">식사류</option>
      <option value="요리류">요리류</option>
    </select>
  </div>
  <div>
  <label for = "name">음식이름:</label>
  <input type="text" name="lion_name">
  </div>
  <div>
  <label for="price">가격:</label>
  <input type="text" name="price">
  </div>
  <div>
  <label for="description">소개:</label>
  <textarea name="description" rows="4" cols="50"></textarea>
  </div>
  <div>
    <p>Takeout 가능한 식품?</p>
    <input type="radio" name="takeout" value="yes" id="takeout_yes">
    <label for="takeout_yes">포장만 가능</label><br>
    <input type="radio" name="takeout" value="no" id="takeout_no">
    <label for="takeout_no">매장내식사만 가능한</label>
  </div>
  <input type="submit" value="제출">
</form>

업로드된 파일을 root 디렉토리의 media 폴더에 저장하는 방법

# config/settings.py
#...
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR/'media'
# config/urls.py
from django.urls import path, include
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path("c/", include("chinese.urls")),
]+ static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

1. HTML 폼에서의 텍스트 입력

<form>
    <label for = "username">이름:</label>
    <input type="text" id="username" name="username">
</form>

2. HTML 폼에서의 다중행 텍스트 입력

<form>
    <label for="bio">소개:</label>
    <textarea id = "bio" name="bio" rows="4" cols="50"></textarea>
</form>

3. HTML 폼에서의 라디오 버튼

<form>
    <p>성별:</p>

    <input type="radio" id="male" name="gender" value="male">
    <label for="male">남자</label><br>

    <input type="radio" id="female" name="gender" value="female">
    <label for="female">여자</label>
</form>

4. HTML 폼에서의 체크박스

<form>
    <label><input type="checkbox" name="hobby" value="sports">스포츠</label>
    <label><input type="checkbox" name="hobby" value="reading">독서</label>
</form>

5. HTML 폼에서의 드롭다운 메뉴

<form>
    <label for="car">차량 선택:</label>
    <select id="car" name = "car">
        <option value="hyundai">현대</option>
        <option value="kia">기아</option>
        <option value="samsung">삼성</option>
    </select>
</form>

6. HTML 폼에서의 파일 업로드

<form action="/upload/" method="post" enctype="multipart/form-data">
    <label for="file">파일 업로드:</label>
    <input type="file" id="file" name="file">
    <input type="submit" value="Upload File">
</form>

Django에서 파일 업로드 처리하기

#app/views.py
from django.views.decorators.http import require_http_methods
from django.core.files.storage import FileSystemStorage
from django.http import HttpResponse
from django.shortcuts import render

@require_http_methods(["GET","POST"])
def upload_file(request):
    if request.method == 'POST':
        uploaded_file = request.FILES['file']
        fs = FileSystemStorage()
        name = fs.save(uploaded_file.name,uploaded_file)
        url = fs.url(name)
        return HttpResponse(f"File uploaded at {url}")
    return render(request,'upload.html')

7. HTML 폼에서의 날짜 선택

<form>
    <label for="birthday">생일:</label>
    <input type="date" id="birthday" name="birthday">
</form>

GET vs POST

  • 데이터의 위치 GET은 URL에 POST는 HTTP 본문에 데이터를 포함
  • 보안 POST가 더 안전
  • 데이터 양 POST가 더 많은 데이터를 전송
  • 캐싱과 북마크 GET 요청은 캐시되고 북마크할 수 있으나, POST는 그렇지 않음

"캐시되지 않는다"
웹 브라우저가 해당 요청의 응답을
로컬 캐시에 저장하지 않는다는 것을 의미
(이는 웹 브라우저가 같은 요청을 다시 보낼 때
매번 서버로부터 새로운 응답을 받아야 한다는 것을 의미)

"브라우저 히스토리에 저장되지 않는다"
해당 요청이 브라우저의 방문 기록에 기록되지 않는다는 것을 의미
(즉, 사용자의 브라우저 히스토리에는
해당 요청이 포함되지 않으며,
사용자는 뒤로가기 버튼을 클릭하여
이전 페이지로 돌아갈 수 없음)

캐시는 요청에 대한 응답
히스토리는 요청

profile
개발자

0개의 댓글