유저와 게시글, 게시글과 댓글의 연결
User와 다른 모델 간의 모델 관계 설정
- User & Article
- User & Comment
모델 관계 설정
# articles/models.py
from django.conf import settings
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
User 모델을 참조하는 2가지 방법
- get_user_model()
- settings.AUTH_USER_MODEL
django 프로젝트 ‘내부적인 구동 순서’와 ‘반환 값’에 따른 이유
기억할 것은 User 모델은 직접 참조하지 않는다는 것
get_user_model() | settings.AUTH_USER_MODEL | |
반환 값 | User Object (객체) | ‘accounts.USER’ (문자열) |
사용 위치 | models.py가 아닌 다른 모든 위치 models.py가 아닌 다른 모든 위치 | models.py |
models.py 에서는 문자열로 참조해야된다. 내부적인 구동 순서에 따라서 존재하지 않은 User 객체를 가져올 수 없기 때문에 문자열로 가져오고 나중에 대체된다는 개념
Migration
- makemigration
- 기존에 테이블이 있는 상황에서 필드를 추가 하려하기 때문에 발생하는 과정
- 기본적으로 모든 필드에는 NOT NULL 제약조건이 있기 때문에 데이터가 없이는 새로운 필드가 추가되지 못함
- ‘1’을 입력하고 Enter 진행( 다음 화면에서 직접 기본 값 입력)
- Provide a one-off default now (will be set on all existing rows with a null value for this column)
- 추가하는 외래 키 필드에 어떤 데이터를 넣을 것인지 직접 입력해야 함
- 마찬가지로 1을 입력하고 Enter 진행
- ⇒ 기존에 작성된 게시글이 있다면 모두 1 번 회원이 작성한 것으로 처리됨
Please enter the default value as valid Python. The datetime and django.utils.timezone modules are available, so it is possible to provide e.g. timezone.now as a value. Type 'exit' to exit this prompt
게시글 CREATE
- 기존 Article 출력 변화 확인 할 시 User 모델에 대한 외래 키 데이터 입력을 받기 위한 불필요한 input이 출력되고있음
- 출력 필드 수정
# articles/forms.py
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
# fields = '__all__'
fields = ('title','content',)
- 게시글 작성 시 에러 발생 = user_id 필드 데이터가 누락되었기 때문
- 게시글 작성 시 작성자 정보가 함께 저장될 수 있도록 save의 commit 옵션 활용
# articles/views.py
@login_required
def create(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
# article = form.save()
# save() 하기 전에 user 정보를 article.user에다가 넣어줘야 된다.
article = form.save(commit=False)
article.user = request.user
article.save()
return redirect('articles:detail', article.pk)
게시글 Read
<!-- articles/index.html -->
<p>작성자 : {{article.user}} <p>
<!-- articles/detail.html -->
<p>작성자 : {{article.user}} <p>
게시글 update
본인의 게시글만 수정 할 수 있도록 하기
- 게시글 수정 요청 사용자와 게시글 작성 사용자를 비교
# articles/views.py
@login_required
def update(request, pk):
article = Article.objects.get(pk=pk)
if request.method == 'POST':
form = ArticleForm(request.POST, instance=article)
if form.is_valid():
form.save()
return redirect('articles:detail', article.pk)
else:
form = ArticleForm(instance=article)
→
@login_required
def update(request, pk):
article = Article.objects.get(pk=pk)
if request.user == article.user: # 작성한 사용자가 아닐 경우
if request.method == 'POST':
form = ArticleForm(request.POST, instance=article)
if form.is_valid():
form.save()
return redirect('articles:detail', article.pk)
else:
form = ArticleForm(instance=article)
else:
return redirect('articles:index') # 메인페이지로 되돌려버려라
- 해당 게시글 작성자가 아니라면, 수정/삭제 버튼을 출력하지 않도록 하기
<!-- articles/detail.html -->
{% if request.user == article.user %}
<a href="{% url "articles:update" article.pk %}">UPDATE</a>
<form action="{% url "articles:delete" article.pk %}" method="POST">
{% csrf_token %}
<input type="submit" value="DELETE">
</form>
{% endif %}
수정할 때는 인스턴스를 받기 때문에, 생성할 때처럼 save의 commit 옵션 활용을 안해도 된다.
게시글 delete
# articles/views.pt
@login_required
def delete(request, pk):
article = Article.objects.get(pk=pk)
# 조건 추가
if request.user == article.user:
article.delete()
return redirect('articles:index')
Comment & User
모델 관계 설정
Comment에도 동일한 과정
댓글 CREATE
게시글 작성 때처럼 user_id 필드 데이터 누락 문제 발생
# articles/views.py
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.article = article
comment.user = request.user # 추가
comment.save()
댓글 READ
댓글 출력 시 댓글 작성자와 함께 출력
<!-- articles/detail,html -->
{% for comment in comments %}
<li>
{{comment.user }} - {{ comment.content }}
...
</li>
{% endfor %}
댓글 DELETE
본인의 댓글만 삭제할 수 있도록 하기
댓글 삭제 요청 사용자와 댓글 작성 사용자를 비교
# articles/views.py
def comments_delete(request, article_pk, comment_pk):
comment = Comment.objects.get(pk=comment_pk)
if request.user == comment.user:
comment.delete()
return redirect('articles:detail', article_pk)
<!-- articles/detail.html -->
{% if request.user == comment.user %}
<form action="">
<input type="submit" value="삭제">
</form>
{% endif %}
참고
인증된 사용자만 댓글 작성 및 삭제
# articles/views.py
@login_required
def comments_create(request, pk):
pass
@login_required
def comments_create(request, article_pk, comment_pk):
pass