Django CRUD - 6. Create(2)

Mingi Shin·2023년 2월 14일
0

CRUD

목록 보기
7/11

만든 모델을 가지고 학기와 과목들을 추가하는 기능을 만들어보자.

일단 메인 페이지를 보면

1. Semester Create

먼저 학기를 추가하는 버튼을 만들어보자.

<!-- templates/sju/semester_list.html -->
<a href="{% url 'sju:semester_create' %}" class="btn btn-primary">학기 추가등록</a>

버튼을 누르면 sju:semester_create 라는 별칭이 등록된 url로 이동한다.

# sju/urls.py

path('semester/create/', views.semester_create, name="semester_create"),

semester_create 별칭에 해당하는 path를 추가해줬다. view 함수를 만들어주기 전에 form에 대해 살펴보자. 폼은 페이지 요청시 전달되는 매개변수들을 쉽게 관리하기 위해 쓰이는 class다.

# sju/forms.py

from django import forms
from sju.models import Semester, Subjects

class SemesterForm(forms.ModelForm):
    class Meta:
        model = Semester
        fields = ['table', 'credits', 'grade']

SemesterForm이 모델폼을 상속했는데 이럴 경우 Meta라는 이너 클래스가 필요하다. Metra에는 사용할 모델과 모델의 속성을 정의한다.

# sju/views.py

def semester_create(request):
    if request.method == 'POST':
        form = SemesterForm(request.POST)
        if form.is_valid():
            semester = form.save(commit=False)
            semester.create_at = timezone.now()
            semester.save()
            return redirect('sju:index')
    else:
        form = SemesterForm()
    context = {'form': form}
    return render(request, 'sju/semester_form.html', context)

create의 경우 POST와 GET을 분리해야 한다. (이미 전에 학습함)
GET 방식으로 들어오면 SemesterForm을 생성하고 sju/semester_form.html을 렌더링한다.

<!-- templates/sju/semester_form.html -->
<div>
    <h5>학기 등록</h5>
    <form method="post">
        {% csrf_token %}
        {{form.as_p}}
        <button type="submit" class="btn btn-primary">등록하기</button>
    </form>
</div>

{{% csrf_token %}}은 많이 본 듯 하다. 이전 단계의 실습에서 views함수에 POST요청시 장고 보안을 피하기 위해 @csrf_exempt를 해주었다. 이와 같은 개념으로 html 파일에서 장고 보안을 스킵하는 것이다.

{{form.as_p}}의 form은 semester_create에서 전달받은 SemesterForm의 객체다. SemesterForm의 이너 클래스 정의에서 사용한 시간표, 이수 학점, 학점 평점에 대한 필드(속성)들의 코드를 생성한다.

form 태그를 보면 평소와 달리 action 속성을 정의하지 않았다. 원래는 submit 버튼을 누르면 정의된 action 속성의 url로 form을 전송할텐데 말이다. 이를 생략할 경우 현재 페이지의 url로 전송한다는 의미다. 만약 속성을 지정하게 되면 action="{% url 'sju/semester_create %}"가 될 것이다. (포스트 방식으로 한 번 더 보내야 하니까!)

def semester_create(request):
    if request.method == 'POST':
        form = SemesterForm(request.POST)
        if form.is_valid():
            semester = form.save(commit=False)
            semester.create_at = timezone.now()
            semester.save()
            return redirect('sju:index')

이제 semester_create 함수로 돌아가면 이제 request.method=="POST" 분기에 함수가 걸리게 될 것이다. form에 입력했던 SemesterForm을 저장한다. 이후 semester 변수에 폼을 임시 저장하고 생성 시간을 만들어주고 semester 객체를 세이브한다. 그 후 메인 페이지로 리턴한다.

학기를 하나 추가해보자

내용을 입력하자

군대 가기 직전 나는 학교를 놀러다녔다. 15학점 들었다.

Semester 객체가 하나 생성되면서 메인 페이지의 리스트가 하나 추가 되었다.

이렇게 Semester에 대한 상세 페이지를 read할 수 있다. 밑에 보이는 과목 등록 칸, 버튼은 미리 만듬

base.html

우리가 여태 작성한 html 파일은 보통의 html 파일 형식과 좀 다르다. 그런데 지금까지 만든 페이지들은 공통의 html 형식을 공유한다. 이 경우 base가 되는 html 파일을 하나 만들고 세부적인 것들을 import 하는 식으로 템플렛을 관리하는 것이 효율적이다.(앞서 baseHTML 함수를 정의하고 index, create, read, 등등 article을 각각 만들어 baseHTML 함수에 request 한 것과 같은 개념)

!에 tap 만 누르면 된다.
body를 보면 'navbar.html'을 include 했는데 navbar.html은 페이지의 상단 부분을 나타내는 코드를 갖고 있는 파일이다. 페이지의 상단 부분은 create 페이지든, read 페이지든, 동일한 템플렛을 사용하기 때문에 base.html에 include 했다.

메인 로고와 함께 로그인이라는 링크를 걸어두었는데 나중에 활용할 것이기 때문에 #으로 했다. 끄읕 ~

2. Subjects Create

학기 등록도 했으니 학기에 대한 과목 등록도 만들자.

<!-- sju/semester_read.html -->
<form action="{% url 'sju:subject_create' sem.id %}" method="post">
{% csrf_token %}
<p><input type="text" name="name" placeholder="Subject Name"></p>
<p><input type="text" name="credit" placeholder="Credit"></p>
<p><input type="submit" value="이수 과목 등록"></p>
</form>

semester에 대한 read 페이지 밑에 폼을 만들어준다. 입력 후 등록 버튼을 누르면 subject_create 별칭에 해당하는 url로 이동한다.

path('subject/create/<int:sem_id>/', views.subject_create, name='subject_create'),
그래서 urls.py에 path를 추가했다. 그럼 subject_create함수를 뷰에 만들어야지.

# sju/forms.py

class SubjectsForm(forms.ModelForm):
    class Meta:
        model = Subjects
        fields = ['name', 'credit']

name은 이제 과목 이름. credit은 이제 과목에 대한 인정되는 학점

def subject_create(request, sem_id):
    semester = get_object_or_404(Semester, pk=sem_id)
    
    if request.method == "POST":
        form = SubjectsForm(request.POST)
        if form.is_valid():
            subjects = form.save(commit=False)
            subjects.create_at = timezone.now()
            subjects.semester = semester
            subjects.save()
            return redirect('sju:read', sem_id=semester.id)
    else:
        return HttpResponseNotAllowed('Only POST is possible.')
    context = {'semester': semester, 'form':form}
    return redirect(request, 'sju/semester_read.html', context)

과목 등록 함수는 GET 방식이 없다는 것. GET으로 오면 오류를 내고, POST로만 처리하도록.

form에 입력한 SubjectsForm을 저장한다. 필드가 name, credit이 있었으니 두 개가 저장될 것이다. create_at 속성이 빠져 있으니 현 시간으로 설정해주고 과목을 저장한다. 저장 후 저장한 semester에 대한 read page로 redirect 한다.

아까 만든 semester에 과목을 추가하려고 한다.

나는 미시경제학을 들었었다. (수요곡선과 생산함수가 모시기 조시기~)

등록하면 이렇게 짠.

profile
@abcganada123 / git:ABCganada

0개의 댓글