장고 사용자 문의 기능 만들기
사용자 문의 페이지를 만든 이유는 애플 앱 제작 가이드라인에서 필수 사항이기 때문이다. 이 기능은 사용자들이 궁금한 점이나 요청사항을 작성할 수 있는 공간을 제공하여, 사용자와 관리자가 소통할 수 있는 중요한 요소다.
사용자 문의 모델 만들기
먼저, 사용자가 남길 수 있는 문의 사항을 저장할 Inquiry 모델을 만들었다. 이 모델은 문의 제목, 내용, 작성자 정보를 포함해야 했다. 아래와 같은 코드를 작성했다:
from django.db import models
from django.contrib.auth.models import User
class Inquiry(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
subject = models.CharField(max_length=200)
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.subject
모델을 정의하는 과정이 즐거웠다. 각 문의가 언제 작성되었는지를 기록하기 위해 created_at 필드도 추가했다.
문의 작성 폼 만들기
그 다음으로, 사용자가 문의를 작성할 수 있는 폼을 정의했다. 장고의 ModelForm을 이용해 InquiryForm 클래스를 만들었다. 사용자가 제목과 내용을 입력할 수 있게 했다:
from django import forms
from .models import Inquiry
class InquiryForm(forms.ModelForm):
class Meta:
model = Inquiry
fields = ['subject', 'message']
이 폼 덕분에 사용자는 간편하게 문의 사항을 제출할 수 있게 되었다.
클래스 기반 뷰 설정하기
이제 사용자 문의를 처리할 뷰를 설정했다. 장고의 클래스 기반 뷰(Class-Based Views)를 활용해 InquiryCreateView를 만들었다. 이 뷰는 사용자가 입력한 문의를 데이터베이스에 저장하는 역할을 한다. 로그인한 사용자만 접근할 수 있도록 LoginRequiredMixin을 사용했다.
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import CreateView
from .models import Inquiry
from .forms import InquiryForm
class InquiryCreateView(LoginRequiredMixin, CreateView):
model = Inquiry
form_class = InquiryForm
template_name = 'helps/inquiry_form.html'
success_url = reverse_lazy('inquiry_success')
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
클래스를 정의하면서 코드의 재사용성과 가독성이 높아졌다. 특히 form_valid 메서드를 통해 현재 로그인한 사용자의 정보를 문의와 연결하는 부분이 뿌듯했다.
답변 모델 생성
사용자의 문의에 대한 답변을 저장하기 위해 Response 모델을 추가했다. 이 모델은 각 문의와 연결되어 있다. 답변 내용 및 작성자 정보를 포함한다:
class Response(models.Model):
inquiry = models.ForeignKey(Inquiry, on_delete=models.CASCADE, related_name='responses')
user = models.ForeignKey(User, on_delete=models.CASCADE)
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Response to {self.inquiry.subject} by {self.user.username}"
여기서 related_name 속성을 사용해 문의와 답변 간의 관계를 쉽게 조회할 수 있도록 했다.
답변 폼 생성
이제 관리자가 문의에 답변할 수 있도록 ResponseForm을 만들어야 했다. 이 폼은 답변 내용을 입력할 수 있게 해준다:
from .models import Response
class ResponseForm(forms.ModelForm):
class Meta:
model = Response
fields = ['message']
문의 상세보기 뷰 추가
사용자가 작성한 문의와 그에 대한 답변을 확인할 수 있도록 InquiryDetailView를 생성했다. 이 뷰는 문의 상세 정보를 보여주고, 답변을 작성할 수 있는 폼을 포함한다:
from django.views.generic import DetailView
class InquiryDetailView(LoginRequiredMixin, DetailView):
model = Inquiry
template_name = 'helps/inquiry_detail.html'
context_object_name = 'inquiry'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['response_form'] = ResponseForm()
context['responses'] = self.object.responses.all()
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = ResponseForm(request.POST)
if form.is_valid():
response = form.save(commit=False)
response.inquiry = self.object
response.user = request.user
response.save()
return redirect('inquiry_detail', pk=self.object.pk)
return self.get(request, *args, **kwargs)
이 뷰 덕분에 사용자는 자신의 문의에 대한 답변을 쉽게 확인하고 추가할 수 있게 되었다.
URL 설정
각 뷰에 대한 URL 패턴을 설정했다. helps/urls.py 파일에 다음과 같이 추가했다:
from django.urls import path
from .views import InquiryCreateView, InquirySuccessView, InquiryDetailView
urlpatterns = [
path('inquiry/', InquiryCreateView.as_view(), name='inquiry_form'),
path('inquiry/success/', InquirySuccessView.as_view(), name='inquiry_success'),
path('inquiry/<int:pk>/', InquiryDetailView.as_view(), name='inquiry_detail'),
]
템플릿 작성
마지막으로, 사용자 문의 및 답변 기능을 위한 템플릿을 작성했다. 문의 작성 페이지(inquiry_form.html)와 문의 상세보기 페이지(inquiry_detail.html)를 만들어 사용자 인터페이스를 구현했다.
문의 작성 페이지 (inquiry_form.html):
<h2>문의하기</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">문의 보내기</button>
</form>
문의 상세보기 페이지 (inquiry_detail.html):
<h2>{{ inquiry.subject }}</h2>
<p><strong>문의 내용:</strong> {{ inquiry.message }}</p>
<p><strong>작성자:</strong> {{ inquiry.user.username }}</p>
<p><strong>작성일:</strong> {{ inquiry.created_at }}</p>
<h3>답변:</h3>
{% for response in inquiry.responses.all %}
<div>
<strong>{{ response.user.username }}</strong> ({{ response.created_at }}):
<p>{{ response.message }}</p>
</div>
{% empty %}
<p>아직 답변이 없습니다.</p>
{% endfor %}
<h3>답변 작성하기:</h3>
<form method="post">
{% csrf_token %}
{{ response_form.as_p }}
<button type="submit">답변하기</button>
</form>
마이그레이션 및 테스트
모든 준비가 끝난 후, 데이터베이스에 새로운 모델을 반영하기 위해 마이그레이션을 수행했다:
python manage.py makemigrations
python manage.py migrate
이제 포럼 사이트에 사용자가 문의를 작성하고, 관리자가 그에 대한 답변을 추가할 수 있는 기능이 완성되었다. 사용자가 자신의 질문에 대한 답변을 쉽게 받을 수 있는 환경이 조성되었다.
이렇게 멋진 기능을 추가하며, 사용자와의 소통을 더 원활하게 할 수 있어서 기쁘다. 다음에는 더 많은 기능을 추가하고, 사이트를 더욱 발전시킬 방법을 고민할 예정이다.