본문 바로가기
개발/Django

[Django] 게시판 권한 설정해보기

by char_lie 2023. 4. 12.
반응형

django를 활용하여 게시판 권한을 설정해 보자

코드는 아래 링크 내용에서 이어진다. 

https://edder773.tistory.com/169

 

[Django] 게시판 댓글 기능 구현 해보기 - Part 3

django를 활용하여 게시판 댓글 기능을 구현해 보자. 코드는 아래 링크 내용에서 이어진다. https://edder773.tistory.com/162 [Django] 게시판 댓글 기능 구현 해보기 - Part 2 django를 활용하여 게시판 댓글 기

edder773.tistory.com

사용자가 작성한 게시글의 권한을 설정해 보자 


User 모델을 참조하는 방법

  1. setting.AUTH_USER_MODEL
    • User 모델에 대한 외래 키나 M:N 관계 정의 시 사용
    • 'accounts.User'의 반환값을 가짐
    • models.py의 모델 필드에 User 모델 참조할 때 사용
  2. get_user_model()
    • 현재 활성화된 User모델 반
    • 'User Object'의 반환값을 가짐
    • models.py가 아닌 다른 모든 곳에서 유저 모델을 참조할 때 사용

모델의 관계를 설정해 주기 위해서 articles의 models.py에서 Article 클래스에 다음과 같이 user를 추가해주자.

# articles/models.py

from django.db import models
from django.conf import settings

class Article(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=10)
    content = models.TextField()
    image = models.ImageField(blank = True)

class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete = models.CASCADE)
    content = models.CharField(max_length=100)
    def __str__(self):
        return self.content

models.py를 수정했으니, 저장 후 필수적으로 migrate를 진행해 주자.

makemigrate를 진행할 경우 아래와 같은 경고문이 뜬다.

기본적으로 모든 칼럼은 NOT NULL 제약 조건이 있어서 데이터 없이 새로 추가되는 외래 키 필드 user_id가 생성되지 않으므로 기본값을 어떻게 할지 선택해야 한다.

1을 입력 후 진행해 주자

article의 user_id에도 어떤 데이터를 넣을지 입력하라는 경고가 뜬다. 1을 입력하고 진행하자.

그러고 나서 다시 migrate를 진행해 주자.

여기까지 user를 만들었다면, 이제 다른 게시글에 대해 인증된 회원만 게시글을 작성할 수 있도록 코드를 수정해 주자.

먼저 글 작성 시에, model을 수정해 주어서 form에 불필요한 user필드가 출력이 되므로 exclude를 이용해 user필드를 제외한 나머지를 출력할 수 있게 수정해 주자.

# articles/forms.py

from django import forms
from .models import Article, Comment

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        exclude = ('user',)
        
class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('content',)

이제 게시글 작성 시, 작성자 정보가 함께 저장될 수 있도록 create 함수를 변경해 주자. save의 commit 옵션을 활용해야 한다.

def create(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST,request.FILES)
        if form.is_valid(): #유효성 검사
           article = form.save(commit=False)
           article.user = request.user
           article.save()
           return redirect('articles:read', pk=article.pk)
    else:
        form = ArticleForm()
    content = {'form':form}
    return render(request, 'articles/create.html',content)

이제 게시글에 작성자의 id에 대한 정보도 함께 저장이 되기 때문에 삭제 시에도 게시글을 작성한 본인만 삭제할 수 있도록 구상해 주자.

def read(request, pk):
    article = Article.objects.get(pk=pk) # pk값을 받아지정
    if request.method == 'POST':
        if request.user.is_authenticated:
            if request.user == article.user:
                article.delete()
                return redirect('articles:index')
        return redirect('articles:index')
    else :
        commentform = CommentForm()
        comment = article.comment_set.all()
        content = {'article': article, 'commentform' : commentform, 'comment': comment,}
        return render(request, 'articles/read.html', content)

삭제와 동일하게 수정도 본인만 가능하도록 수정해 주자.

def update(request, pk):
    article = Article.objects.get(pk=pk)
    if request.user == article.user:
        if request.method == 'POST':
            form = ArticleForm(request.POST, request.FILES, instance=article)
            if form.is_valid():
                form.save()
                return redirect('articles:read', pk=article.pk)
        else:
            form = ArticleForm(instance=article)
        content = {'form':form, 'article': article, }
        return render(request, 'articles/update.html', content)
    else :
        return redirect('articles:index')

추가로 해당 게시글의 작성자가 아니라면 수정, 삭제 버튼이 출력되지 않게 index와 read html을 수정해 보자.

{% if request.user == article.user %}
<a href="{% url 'articles:update' article.pk %}">수정하기</a>
{% endif %}

read.html을 고쳤으니 index.html도 고쳐주

{% if request.user == article.user %}
<form action="{% url 'articles:read' article.pk %}" method="POST" >
    {% csrf_token %}
    <input type="submit" value="삭제하기" >
</form>
{% endif %}

마지막으로 각 게시글의 작성자가 누군지 표시를 해주자.

{% for article in articles %}
<p>작성자 : {{article.user}}</p>
<p>글 번호 : {{article.id}}</p>
<p>글 제목 : {{article.title}}</p>
<p>글 내용 : {{article.content}}</p>
<a href="{% url 'articles:read' article.pk %}">상세내용</a>

여기까지 작성 후 서버를 동작해서 정상적으로 작동하는지 확인해 보자

정상적으로 작성자 이름이 나오고, 본인이 만든 게시글만 삭제할 수 있도록 출력된 것을 확인할 수 있다.

본인이 작성한 글에서 마찬가지로 수정할 수 있지만, 본인이 작성한 글은 수정할 수 없게 수정해 주었다.

 

반응형

댓글