My Image

Django 포스팅

[Django] 장고에서 CRUD로 로그인없이 댓글 기능 구현하기

Doyeon0430 | 2023년 05월 27일

Django 이미지

이번시간에는 로그인 없이 댓글 기능을 추가하겠습니다.

CRUD 개념을 사용해 데이터베이스에 값을 등록시키고 하루의 3번만 입력하도록 제한하겠습니다.

추가적으로 자바스크립트를 사용해서 에러메시지가 생기도록 이벤트 함수를 구현하겠습니다.

 

  1. CRUD 댓글기능 만들기 - models.py

  2. CRUD 댓글기능 만들기 - forms.py

  3. CRUD 댓글기능 만들기 - views.py

  4. CRUD 댓글기능 만들기 - JavaScript

  5. forms.errors가 동작을 안한다면?

 

 

1. CRUD 댓글기능 만들기 - models.py

models.py

class Comment(models.Model):
    mywork = models.ForeignKey(Mywork, on_delete=models.CASCADE, related_name='comments')
    username = models.CharField(max_length=200)
    password = models.CharField(max_length=200)
    content = HTMLField()
    create_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'[{self.mywork.pk}. {self.mywork.subject}] {self.username}님'

Mywork라는 객체에 댓글 기능을 추가하고자 참조키를 이용해 새로운 모델을 생성했습니다.

__str__을 살펴보면 장고 관리자에 보여지는 문자열로 댓글을 쉽게 식별하고자 작성했습니다.

 

 

2. CRUD 댓글기능 만들기 - forms.py

forms.py

from django import forms
from .models import Comment

class CommentForm(forms.ModelForm):
    username = forms.CharField(
        max_length=200,
        label="사용자 이름",
        error_messages={'required': '아이디를 입력해 주세요'}
    )
    password = forms.CharField(
        widget=forms.PasswordInput(),
        label="비밀번호",
        error_messages={'required': '비밀번호를 입력해 주세요'}
    )

    class Meta:
        model = Comment
        fields = ['username', 'password', 'content']

form.py를 새로 생성하고 commentForm이라는 클래스를 선언해야합니다.

commentForm이 views.py에서 사용자 데이터를 입력받는 기능입니다.

 

 

3. CRUD 댓글기능 만들기 - views.py

views.py

from .forms import CommentForm

@csrf_exempt
def detail(request, mywork_id):
    detail = get_object_or_404(Mywork, pk=mywork_id)
    comments = Comment.objects.filter(mywork=detail.pk)

    if request.method == 'POST':
        form = CommentForm(request.POST)
        password = request.POST.get('password')
        comment_id = request.POST.get('comment_id')

        if form.is_valid():
            if comment_count < 3:
                comment = form.save(commit=False)
                comment.mywork = detail
                comment.save()
                form = CommentForm()  # Clear the form after saving the comment
                return redirect('mywork:detail', mywork_id=mywork_id)
        
        try:
            comment = Comment.objects.get(pk=comment_id)
            if password == comment.password:
                comment.delete()
                return redirect('mywork:detail', mywork_id=mywork_id)
            
        except Comment.DoesNotExist:
            pass

    else:
        form = CommentForm()
    context = {'detail': detail, 'comments': comments, 'form': form}

    return render(request, 'mywork/detail.html', context)

is_valid()는 데이터에 값이 정상적으로 들어왔는지 구별해주는 함수입니다.

만약 값이 이상하면 form.errors으로 전달되고 오류메시지를 생성합니다.

try는 생성된 댓글에 삭제기능을 추가하고자 만들었습니다.

if문으로 입력받은 password와 쿼리에 있는 comment.password가 일치하면 해당 값이 삭제됩니다.

request.method에서 post 요청이 안들어 왔을 때 정상적으로 실행시키게 만들었습니다.

 

 

4. CRUD 댓글기능 만들기 - JavaScript

JavaScripts 코드

{% if form.errors %}
<script>
  // JavaScript 코드를 이용하여 경고 메시지 표시
  document.addEventListener('DOMContentLoaded', function() {
    var errorMessage = '잘못된 내용입니다.'; // 경고 메시지 내용
    alert(errorMessage); // 경고 메시지 표시
    history.replaceState({}, document.title, window.location.href.split('?')[0]); // URL 파라미터 제거
  });
</script>
{% endif %}

자바스크립트는 오류메시지를 생성합니다.

is_valid()가 실패하면 {{form.errors}}가 작동합니다.

오류메시지를 띄운 다음 url 파라미터를 제거해야합니다.

 

 

5. form.errors가 동작을 안한다면?

만약 is_vaild()에 실패해도 {{form.errors}}가 작동안할 때 있습니다.

 

1. HTML 코드

<form method="post">
     {% csrf_token %}
     {{ form.as_p }}
     <button type="submit">Submit</button>
</form>

위의 코드처럼 템플릿을 사용하면 실패해도 {{form.errors}}가 작동을 안합니다.

 

2. HTML 코드

<form method="post">
<label for="username">ID</label>
<input type="text" name="username" id="username" value="{{ form.username.value|default_if_none:'' }}">

<label for="password">비밀번호</label>
<input type="password" name="password" id="password" value="{{ form.password.value|default_if_none:'' }}">

<label for="content">댓글</label>
<textarea name="content" id="content">{{ form.content.value|default_if_none:'' }}</textarea>

<button type="submit">Submit</button>
</form>

이런식으로 수정해줘야 제대로 작동합니다.

글을 마치며 로그인 과정 없이 ID와 PW를 입력해서 댓글남기는 기능을 만들어봤습니다.

댓글 (0)

    댓글이 없습니다.

간편 댓글 작성

My Image My Image My Image My Image