티스토리 뷰

Python

[Django 입문] 모델 폼 만들기

Alledy 2019. 11. 12. 16:52

모델 폼 만들기

폼클래스 정의하는 법을 배웠는데, 모델 폼은 그보다 더 간단하다. 폼을 만들 때에 DB 업데이트가 목적이라면 모델 폼을 쓰는 것이 훨씬 편하다.

폼클래스를 만드려면 원래 필드를 다 지정해줘야 한다. 하지만 모델폼을 사용하면 모델에 있는 필드를 가져다가 쓸 수 있다.

from django import forms
from .models import Score, Movie


# class ScoreForm(forms.Form):
#     content = forms.CharField(
#         max_length=100,
#         label='한줄평',
#         widget=forms.TextInput(attrs={
#             'class': 'score-content',
#             'placeholder': '한줄평을 작성해주세요'
#         })
#     )
#     score = forms.IntegerField(
#         required=True,
#         label='평점',
#         min_value=0,
#         widget=forms.NumberInput(attrs={
#             'class': 'score'
#         })
#     )

class ScoreForm(forms.ModelForm):
    class Meta:
        model = Score
        fields = ['content', 'score']  # '__all__' 설정시 전체 필드 추가

주석처리된 부분은 모델폼을 사용하지 않고 그냥 폼클래스를 사용할 때 필드를 전부 지정해준 부분이다. 모델폼을 사용하면 class Meta 에 어떤 모델을 쓸 건지, 그 모델에서 어떤 필드를 갖다 쓸건지 리스트로 지정해준다. 그러면 끝이다.

그 다음 views.py를 수정한다.

def detail(request, pk):
    movie = Movie.objects.get(pk=pk)
    scores = movie.score_set.all()

    if(len(scores) == 0):
        messages.info(request, "아직 등록된 평점이 없습니다.")

    if request.method == 'POST':
        form = ScoreForm(request.POST)
        if form.is_valid():
            # score = form.cleaned_data['score']
            # content = form.cleaned_data['content']
            # Score.objects.create(score=score, content=content, movie_id=pk)
            score = form.save(commit=False)  # 중복 DB save 방지
            score.movie = movie
            score.save()
            return redirect('movies:detail', movie.pk)
    else:
        form = ScoreForm()

    return render(request, 'movies/detail.html', {'movie': movie, 'scores': scores, 'form': form})

주석처리된 부분은 역시 폼클래스를 사용했을 때이다. 유효 데이터는 cleaned_data에 들어가고, 여기서 필드를 하나씩 일일이 꺼내야 했다.

하지만 모델폼은 폼을 통째로 세이브하여 하나의 데이터로 만든다. 이 때 score.movie 는 Score 모델이 외래키로 갖고 있는 movie 필드이다. 이 값은 폼 데이터로 전송받는 값이 아니고 url에서 받는 값이므로 이렇게 따로 설정한다. 그 다음 해당 데이터를 세이브하면 나머지 로직은 같다.

수정하는 경우에는 다음과 같다.

def score_edit(request, score_pk):
    # url로부터 해당 스코어 데이터를 가져옴
    score = get_object_or_404(Score, pk=score_pk)
    
    # 해당 스코어 데이터를 스코어 모덾폼에 넘겨 인스턴스를 생성
    if request.method == 'POST':
        form = ScoreForm(request.POST, instance=score) 
        if form.is_valid():
            score = form.save()
            return redirect('movies:detail', movie.pk)
    else:
        form = ScoreForm(instance=score)
        
    return render(request, 'movies/detail.html', {'movie': movie, 'scores': scores, 'form': form})

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
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
글 보관함