웹 프로그래밍 프로필 및 카테고리 및 코멘트 추가(5부)
이전 Django 기반 Python 웹 프로그래밍 포스팅에서 업로드된 포스트에 삭제 기능과 로그인 기능을 추가했습니다. 이번에는 블로그의 기본 요소인 프로필과 포스트를 구분하는 카테고리와 댓글 기능을 추가해 보겠습니다. 이제 웹 프로그래밍에 대한 포스팅을 시작해서 프로필, 카테고리, 댓글을 추가하겠습니다(5부).
1. 프로필 및 카테고리, 댓글 프로필 및 카테고리, 댓글 위에 언급한 세 가지 기능은 게시물 업로드 및 로그인 기능을 제외한 블로그 운영에 가장 기본적인 기능입니다. 이번에는 스타일 시트 영역을 건드리지 않겠습니다. 지금은 블로그라고 부르기에는 너무 기능이 부족하고 UI와 UX도 형편없지만 프런트엔드와 백엔드 영역을 구현한 후 UI/UX를 개선하여 블로그라는 단어에 맞게 어느 정도 기능할 수 있도록 할 예정이니 참고하시기 바랍니다.
2. 프로필 관리 기능 프로필을 추가하려면 다른 기능을 구현할 때와 마찬가지로 프로필 기능을 구현하는 데 필요한 모델을 만들고, 새 사용자(계정)가 생성될 때마다 자동으로 기본 프로필을 만듭니다. 그런 다음 클라이언트가 프로필을 수정할 수 있는 페이지와 최소한의 인터페이스를 보고 사용할 수 있도록 템플릿을 만들고 URL을 매핑합니다. 이러한 단계를 거친 후 프로필 관리 기능이 추가됩니다. 아래 소스 코드를 참조하세요.
blog1/models.py(클래스 Profile)에 프로필 모델을 생성합니다.
from django.db import modelsfrom django.contrib.auth.models import Userfrom django.utils import timezoneclass Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) bio = models.TextField(blank=True) location = models.CharField(max_length=30, blank=True) birth_date = models.DateField(null=True, blank=True) def __str__(self):return self.user.username signals.py라는 이름의 파일을 만들고 아래 코드를 작성한 후 blog1 디렉터리에 저장합니다. 특수 문자 @가 있는 줄에 작성된 코드는 데코레이터로 간주할 수 있습니다. 작성한 데코레이터는 함수와 메서드에 추가 동작을 추가하는 코드로 생각할 수 있습니다. from django.db.models.signals import post_savefrom django.dispatch import receiverfrom django.contrib.auth.models import Userfrom .models import Profile@receiver(post_save, sender=User)def create_user_profile(sender, instance, created, **kwargs):if created: Profile.objects.create(user=instance)@receiver(post_save, sender=User)def save_user_profile(sender, instance, **kwargs): instance.profile.save() 다음과 같이 blog1/apps.py 파일에 코드를 작성합니다. 작성된 코드는 이전에 작성한 signals.py 파일을 프로젝트에 연결하기 위한 것이라고 생각할 수 있습니다. from django.apps import AppConfigclass Blog1Config(AppConfig): name = ‘blog1’ def ready(self):import blog1.signals 그런 다음 명령 프롬프트를 실행하고 프로젝트 디렉토리가 있는 경로로 이동하여 마이그레이션을 생성하고 적용합니다. blog1/forms.py와 같은 디렉토리에 있는 두 개의 파일 views.py에 프로필에 대한 코드를 추가합니다. forms.py from django import formsfrom .models import Post, Profileclass ProfileForm(forms.ModelForm):class Meta: model = Profile fields = (‘bio’, ‘location’, ‘birth_date’) views.py 아래 코드에서 볼 수 있듯이 프로필 콘텐츠 외에도 이 뷰는 이전에 사용한 데코레이터를 추가하여 이전에 생성된 페이지에는 로그인한 사용자만 액세스할 수 있도록 합니다. django.shortcuts에서 render, get_object_or_404, django.contrib.auth.models에서 리디렉션 가져오기 Userfrom .models 가져오기 Post, Profilefrom .forms 가져오기 PostForm, ProfileFormfrom django.contrib.auth.decorators에서 login_required 가져오기 def post_list(요청): posts = Post.objects.all().order_by(‘-created_at’) return render(요청, ‘blog1/post_list.html’, {‘posts’: posts}) def post_detail(요청, pk): post = get_object_or_404(게시물, pk=pk) return render(요청, ‘blog1/post_detail.html’, {‘post’: post}) def post_new(요청): if request.method == “POST”: form = PostForm(request.POST) if form.is_valid(): post = form.save(commit=False) post.save()return(‘post_detail’, pk=post.pk) else: form = PostForm()return(request, ‘blog1/post_edit.html’, {‘form’: form}) def post_edit(request, pk): post = get_object_or_404(Post, pk=pk) if request.method == “POST”: form = PostForm(request.POST, instance=post) if form.is_valid(): post = form.save(commit=False) post.save()return(‘post_detail’, pk=post.pk) else: form = PostForm(instance=post)return(request, ‘blog1/post_edit.html’, {‘form’: form}) def post_delete(request, pk): post = get_object_or_404(Post, pk=pk) if request.method == “POST”: post.delete()return react(‘post_list’)return render(request, ‘blog1/post_confirm_delete.html’, {‘post’: post})@login_requireddef edit_profile(request):if request.method == ‘POST’: form = ProfileForm(request.POST, instance=request.user.profile)if form.is_valid(): form.save()return react(‘profile’)else: form = ProfileForm(instance=request.user.profile)return render(request, ‘blog1/edit_profile.html’, {‘form’: form})@login_requireddef profile_view(request): profile = get_object_or_404(Profile, user=request.user)return render(request, ‘blog1/profile.html’, {‘profile’: profile}) 템플릿 및 URL 만들기다음 코드를 사용하여 매핑 프로필에 대한 템플릿을 만듭니다. 아래에서 blog1/templates/blog1 경로에 저장한 다음, 프로필 URL에 대한 패턴을 blog/urls.py 파일에 추가합니다. 템플릿 파일 이름은 profile과 edit_profile입니다. HTML(profile, edit_profile)
프로필 수정
blog1/urls.py django.urls에서 가져오기 pathfrom django.contrib.auth 가져오기 views as auth_viewsfrom .views 가져오기 post_list, post_detail, post_new, post_edit, post_delete, edit_profile, profile_viewurlpatterns = (path(‘login/’, auth_views.LoginView.as_view(), name=’login’),path(‘logout/’, auth_views.LogoutView.as_view(), name=’logout’),path(”, post_list, name=’post_list’),path(‘post/
블로그 게시물
모든 카테고리
- 모두
- {{ 카테고리.이름 }}
{% 카테고리의 카테고리에 대한 %}
{% 끝 %}
views.py마지막으로 blog1/view.py 파일에 아래 코드를 추가하고 카테고리에 대한 값을 삽입합니다. from django.shortcuts import render, get_object_or_404, directfrom django.contrib.auth.models import Userfrom .models import Post, Profile, Categoryfrom .forms import PostForm, ProfileFormfrom django.contrib.auth.decorators import login_requireddef post_list(request): category_id = request.GET.get(‘category’)if category_id: posts = Post.objects.filter(category_id=category_id).order_by(‘-created_at’)else: posts = Post.objects.all().order_by(‘-created_at’) categories = Category.objects.all()return render(request, ‘blog1/post_list.html’, {‘posts’: posts, ‘categories’: categories}) 서버를 시작하고 127.0.0.1:8000/admin에 액세스합니다. 액세스하는 경우페이지로 이동하여 로그인하면 BLOG1 앱에 Category 항목이 추가된 것을 확인할 수 있습니다. 오른쪽에 있는 Add 버튼을 클릭하여 원하는 이름으로 Category를 만듭니다. Category를 만든 후 127.0.0.1:8000/post/new/에 접속하면 오른쪽 이미지와 같이 Category를 선택할 수 있는 창이 보입니다. Post를 업로드한 후 127.0.0.1:8000에 접속하면 Category를 선택할 수 있는 텍스트가 보이고, 텍스트를 클릭하면 해당 Category로 이동하는 것을 확인할 수 있습니다. 4. Comments 많은 블로그의 가장 중요한 기능 중 하나가 Comments입니다. Comments는 다른 페이지와 마찬가지로 모델, 폼, 뷰를 추가한 후 이전에 만든 post_detail 템플릿을 수정하여 수정할 수 있습니다. blog1/models.py, forms.py blog1 디렉토리에 있는 models.py 파일의 맨 아래에 아래의 comment 모델 코드를 작성하여 저장한 후 마이그레이션을 생성하여 적용합니다. class Comment(models.Model): post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name=’comments’) author = models.CharField(max_length=100) text = models.TextField() created_at = models.DateTimeField(auto_now_add=True) def __str__(self):return self.text 마이그레이션 후 forms.py 파일의 맨 아래에 아래 코드를 추가합니다. from django import formsfrom .models import Post, Profile, Commentclass CommentForm(forms.ModelForm):class Meta: model = Comment fields = (‘author’, ‘text’) blog1/views.py 뷰 파일에서 post_delete 영역의 코드를 수정하고 2번째 줄의 가져오기 영역에 Comment를 추가하여 댓글 기능을 구현하기 위해 작성한 코드를 로드할 수 있도록 합니다. django.shortcuts에서 render, get_object_or_404, .models에서 가져오기 Post, Profile, Category, Commentfrom .forms에서 가져오기 PostForm, ProfileForm, CommentFormfrom django.contrib.auth.decorators에서 가져오기 login_requireddef post_detail(요청, pk): post = get_object_or_404(게시물, pk=pk) comments = post.comments.all() request.method == ‘POST’인 경우 form = CommentForm(요청.POST) form.is_valid()인 경우 comment = form.save(commit=False) comment.post = post comment.user = request.user comment.save() ‘post_detail’, pk=post.pk를 리디렉션(redirect)으로 반환합니다. 그렇지 않으면 form = CommentForm() 요청, ‘blog1/post_detail.html’, { ‘post’: post, ‘comments’: comments, ‘form’:form}) HTML을 반환합니다. (post_detail) 이전에 작성하여 템플릿 디렉토리에 저장했던 post_detail의 코드를 아래와 같이 수정해 댓글 양식과 댓글 목록을 추가합니다.
{{ 게시물 제목 }}
{{ 게시물.내용 }}
카테고리: {{ post.category.name }}
생성됨: {{ post.created_at }}
업데이트 시간: {{ post.updated_at }}
코멘트
{{ comment.text }} – {{ comment.user.username }}님이 {{ comment.created_at }}에 게시함
{% 비어 있는 %}
아직 댓글이 없습니다.
{% 끝 %}
의견을 추가하다
게시물로 돌아가기 위와 같이 코드를 작성하고 서버를 구동한 후 업로드된 게시글을 보면 아래 이미지처럼 댓글 쓰기 상자가 나오고, 댓글 업로드도 원활하게 되는 것을 확인할 수 있습니다. 5. 결론 이번 웹 프로그래밍, 프로필, 카테고리, 댓글 추가하기(5부) 게시글에서는 제목에서 알 수 있듯이 프로필, 카테고리, 댓글 기능을 추가했습니다. 다만 첫 문단에서 썼듯이 스타일시트 부분은 전혀 신경을 쓰지 않아 시각적인 부분에서는 조금 부족해 보이지만, 조금씩 완성되어 가는 듯합니다. 다음 게시글에서는 다른 기능을 구현하거나 UI/UX 부분을 개선하겠습니다. 이전과 마찬가지로 이 게시글의 내용은 GitHub에 새로 업로드했으니 참고해주시기 바랍니다. GitHub – woong980623/Python-Django-BlogGitHub.github.com에 계정을 만들어 woong980623/Python-Django-Blog 개발에 기여하세요.