RDB : Relational DataBase. 테이블을 통해 데이터 집합을 표현하는 방식의 데이터베이스.
- 계층형 데이터베이스 (1:N)
- 망형 데이터베이스 (N:M)
실습
tutorialdjango 프로젝트를 만들고, startapp blog후, settings.py를 수정해준다.
DB 모델 설계
blog / models.py 에 모델 구현
구현 후 makemigrations, migrate 하기
from django.db import models
from django.contrib.auth.models import User # User 모델을 import
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
head_image = models.ImageField(
upload_to='blog/images/%Y/%m/%d/', blank=True)
file_upload = models.FileField(
upload_to='blog/files/%Y/%m/%d/', blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE) # 1:N 관계. on_delete=models.CASCADE : 유저가 지워지면 게시글들도 모두 지워진다.
tags = models.ManyToManyField('Tag', blank=True) # N:M 관계. 한곳에만 정의하면 된다
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments') # 1:N 관계. related_name : Post에서 Comment를 부를때 사용할 이름
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE) # 1:N 관계.
def __str__(self):
return self.message
class Tag(models.Model):
name = models.CharField(max_length=10, unique=True)
def __str__(self):
return self.name
blog / admin.py 수정
admin계정을 생성 후, admin페이지에서 테스트
from django.contrib import admin
from .models import Post, Comment, Tag
admin.site.register(Post)
admin.site.register(Comment)
admin.site.register(Tag)
tutorialdjango / urls.py 수정
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("blog/", include('blog.urls')),
]
blog / urls.py 추가
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.postlist, name='postlist'),
path('<int:pk>/', views.postdetail, name='postdetail'),
path('tag/<str:tag>/', views.posttag, name='posttag'),
]
blog / forms.py 추가
댓글폼 생성
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ("message")
blog / views.py 수정
from django.shortcuts import render
from .models import Post, Comment, Tag
from .forms import CommentForm
from django.db.models import Q
def postlist(request):
if request.GET.get('q'): # get요청의 q가 있으면
q = request.GET.get('q')
posts = Post.objects.filter(Q(title__icontains=q)|Q(content__icontains=q)|Q(comments__message__icontains=q)).distinct() # comments__message :model에서 related_name으로 설정한 comments인 Comment모델의 message필드
else:
posts = Post.objects.all()
return render(request, 'blog/postlist.html', {'posts':posts})
def postdetail(request, pk):
post = Post.objects.get(pk=pk)
form = CommentForm() # 댓글폼
if request.method == 'POST': # Post 요청이 들어오면
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False) # DB에는 저장하지않는 임시 form으로 저장
comment.author = request.user # author에 request.user 할당
comment.post = post # 해당 댓글이 속하는 post 설정
comment.save() # DB에 저장
return render(request, 'blog/postdetail.html', {'post':post, 'form':form})
def posttag(request, tag):
posts = Post.objects.filter(tags__name__iexact=tag) # tags모델의 name필드가 tag와 완벽하게 일치하는것들
return render(request, 'blog/postlist.html', {'posts':posts})
blog / templates / blog / postlist. html, posdetail.html 추가
<!-- postlist.html -->
<form action="" method="GET">
<input type="text" name="q">
<button type="submit">검색</button>
</form>
{% for i in posts %}
<h1><a href="{% url 'blog:postdetail' i.pk%}">{{ i.title }}</a></h1>
<p>{{ i.content }}</p>
<p>{{ i.author }}</p>
<!-- 관계형 모델에서 접근할때는 all 사용 -->
{% for comment in i.comments.all %}
<p>{{ comment.message }}</p>
{% endfor %}
{% for tag in i.tags.all %}
<p>{{ tag.name }}</p>
{% endfor %}
<hr>
{% endfor %}
<!-- postdetail.html -->
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<p>{{ post.author }}</p>
{% for comment in post.comments.all %}
<p>{{ comment.message }}</p>
{% endfor %}
{% for tag in post.tags.all %}
<a href="{% url 'blog:posttag' tag.name %}">#{{ tag.name }}</a>
{% endfor %}
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit">
</form>
'Django' 카테고리의 다른 글
Django와 SQLite3 (0) | 2023.10.23 |
---|---|
Django 실습(9) 동영상 CRUD 구현하기 (0) | 2023.10.20 |
Django 템플릿 필터 (1) | 2023.10.17 |
Django CBV - 제네릭 뷰 (Generic View) (1) | 2023.10.16 |
Django 실습(7) 클래스 기반 뷰 (Class-Based Views) 이용하기 (1) | 2023.10.16 |