템플렛 파일 만들고 TEMPLATES 변수에 넣어주기
'DIRS': [
BASE_DIR / 'templates'
],
{% include 'navbar.html' %}
{% extends 'main.html' %}
https://docs.djangoproject.com/en/4.0/topics/templates/
<a href="/room/{{room.id}}">
{{}} << 안에 값주기
<a href="{% url 'room' room.id %}">
이런 식으로 변경해줄 수 있음
class Room(models.Model) :
# host =
# topic =
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True) # 없을 수도 있음
# participants =
updated = models.DateTimeField(auto_now=True) # 계속 찍힘
created = models.DateTimeField(auto_now_add=True) # 처음 일때만 찍힘
def __str__(self) :
return str(self.name)
그리고 python mange.py makemigrations 를 통해 따로 추가
그리고 migrate 로 완료
python manage.py createsuperuser ... 그리고 admin 아이디와 패스워드 추가
해당 앱의 admin.py 가서 다음과 같은 코드 치기
from django.contrib import admin
# Register your models here.
from .models import Room
admin.site.register(Room)
그러면 데이터베이스 관리 가능하게 됨
from .models import Room
...
rooms = Room.objects.all() # 을 통해서 데이터 베이스 내부 데이터 다 가져옴
그리고
def home(request) :
rooms = Room.objects.all()
context = {'rooms':rooms}
return render(request, 'base/home.html',context)
def room(request,pk) :
room = Room.objects.get(id=pk)
# room = None
# for i in rooms :
# if i['id'] == int(pk) :
# room = i
context = {'room':room}
return render(request, 'base/room.html',context)
class Message(models.Model) :
# user =
room = models.ForeignKey(Room, on_delete=models.CASCADE) # 자동으로 같이 지워지게 됨
body = models.TextField()
updated = models.DateTimeField(auto_now=True) # 계속 찍힘
created = models.DateTimeField(auto_now_add=True) # 처음 일때만 찍힘
def __str_(self) :
return self.body[0:50]
from django.contrib.auth.models import User
추가
그리고
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Topic(models.Model) :
name = models.CharField(max_length=200)
def __str__ (self) :
return self.name
class Room(models.Model) :
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True) # CASCADE 가 아닌 무효
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True) # 없을 수도 있음
# participants =
updated = models.DateTimeField(auto_now=True) # 계속 찍힘
created = models.DateTimeField(auto_now_add=True) # 처음 일때만 찍힘
def __str__(self) :
return str(self.name)
class Message(models.Model) :
user = models.ForeignKey(User, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE) # 자동으로 같이 지워지게 됨
body = models.TextField()
updated = models.DateTimeField(auto_now=True) # 계속 찍힘
created = models.DateTimeField(auto_now_add=True) # 처음 일때만 찍힘
def __str_(self) :
return self.body[0:50]
그리고 makemigrations 랑 migrate 해주기
그리고 admin 페이지 가서 변경해주기
{% extends 'main.html' %}
{% block content %}
<h1>Home Template</h1>
<div>
<div>
{% for room in rooms %}
<div>
<span>@{{room.host.username}}</span>
<h5>{{room.id}} -- <a href="{% url 'room' room.id %}">{{room.name}}</a></h5>
<small>{{room.topic.name}}</small>
<hr>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
home.html 의 코드를 다음과 같이 변경
{% extends 'main.html' %}
{% block content %}
<div>
<form method="POST" action="">
{% csrf_token %}
<input type="submit" value="Submit">
</form>
</div>
{% endblock content %}
room 폼 만들어주기
그리고 home.html 다음과 같은 코드 추가
<a href="{% url 'create-room' %}">Create Room</a>
from django.forms import ModelForm
from .models import Room
class RoomForm(ModelForm) :
class Meta :
model = Room
field = '__all__' # 보여주고 싶은 것을 선책
exclude = ()
def createRoom(request) :
form = RoomForm()
context = {'form':form}
return render(request, 'base/room_form.html', context)
path('create-room/', views.createRoom, name="create-room"),
{{form.as_p}}
from django.shortcuts import render, redirect
...
def createRoom(request) :
form = RoomForm()
if request.method == 'POST' :
form = RoomForm(request.POST)
if form.is_valid() :
form.save() # 데이터 베이스에 추가
return redirect('home') # url 에 이름 있어서 redirect 가능해짐
context = {'form':form}
return render(request, 'base/room_form.html', context)
Room class 안에 넣어진
class Meta :
ordering = ['-updated','-created'] # '-' 넣어주면 가장 먼저 준 것 먼저 나오고 , 안 주면 가장 나중에 것이 나옴
def updateRoom(request,pk) :
room = Room.objects.get(id=pk)
form = RoomForm(instance=room)
context = {'form': form}
return render(request, 'base/room_form.html',context)
path('update-room/<str:pk>/', views.updateRoom, name="update-room"),
<a href="{% url 'update-room' room.id %}">Edit</a>
if request.method == 'POST' :
form = RoomForm(request.POST, instance=room)
if form.is_valid() :
form.save()
return redirect('home')
업데이트 파일에 추가
{% extends 'main.html' %}
{% block content %}
<form method="POST" action="">
{% csrf_token %}
<p>Are you sure you want to delete "{{obj}}"?</p>
<a href="{{request.META.HTTP_REFERER}}">Go Back</a> // 전 페이지로 다시 돌아가기
<input type="submit" value="Confirm">
</form>
{% endblock content %}
def deleteRoom(request,pk) :
room = Room.objects.get(id=pk)
if request.method == "POST" :
room.delete()
return redirect('home')
return render(request, 'base/delete.html', {'obj':room})
path('delete-room/<str:pk>/', views.deleteRoom, name="delete-room"),
<div>
<h3>Browse Topics</h3>
<hr>
<div>
<a href="{% url 'home' %}">ALL</a>
</div>
{% for topic in topics %}
<div>
<a href="{% url 'home' %}?q={{topic.name}}">{{topic.name}}</a>
</div>
{% endfor %}
</div>
쿼리 url 문
topics = Topic.objects.all()
로 주제 다 가져오기
q = request.GET.get('q') if request.GET.get('q') != None else ''
# topic__ 언더바 두개는 부모의 것을 의미
# icontains 는 적어도 하나의 문자를 포함할 때...
rooms = Room.objects.filter(topic__name__icontains=q)
<form method="GET" action="{% url 'home' %}">
<input type="text" name="q" placeholder="Search Rooms...">
</form>
추가
뷰파일에서
from django.db.models import Q
...
rooms = Room.objects.filter(
Q(topic__name__icontains=q) |
Q(name__icontains=q) |
Q(description__icontains=q)
)
이런 식으로 코드를 변경하면 됨
<h5>{{room_count}} rooms available</h5>
def home(request) :
q = request.GET.get('q') if request.GET.get('q') != None else ''
# topic__ 언더바 두개는 부모의 것을 의미
# icontains 는 적어도 하나의 문자를 포함할 때...
rooms = Room.objects.filter(
Q(topic__name__icontains=q) |
Q(name__icontains=q) |
Q(description__icontains=q)
)
topics = Topic.objects.all()
room_count = rooms.count()
context = {'rooms':rooms, 'topics':topics, 'room_count':room_count}
return render(request, 'base/home.html',context)
{% extends 'main.html' %}
{% block content %}
<div>
<form method="POST" action="">
{% csrf_token %}
<label for="">Username: </label>
<input type="text" name="username" placeholder="Enter Username">
<label for="">Password: </label>
<input type="password" name="password" placeholder="Enter Password">
<input type="submit" value="Login">
</form>
</div>
{% endblock content %}
<form method="GET" action="{% url 'home' %}">
<input type="text" name="q" placeholder="Search Rooms...">
</form>
path('login/',views.loginPage, name="login"),
from django.contrib.auth.models import User
...
def loginPage(request) :
if request.method == 'POST' :
username = request.POST.get('username')
password = request.POST.get('password')
try:
user = User.objects.get(username=usernmae)
except:
context = {}
return render(request, 'base/login_register.html')
from django.contrib import messages
...
try:
user = User.objects.get(username=usernmae)
except:
messages.error(request, 'User does not exist')
from django.contrib.auth.models import User
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
def loginPage(request) :
if request.method == 'POST' :
username = request.POST.get('username')
password = request.POST.get('password')
try:
user = User.objects.get(username=username)
except:
messages.error(request, 'User does not exist')
user = authenticate(request,username=username, password=password)
if user is not None :
login(request, user)
return redirect('home')
else :
messages.error(request, 'Username OR password does not exit')
context = {}
return render(request, 'base/login_register.html')
<a href="/">
<h1>LOGO</h1>
</a>
<form method="GET" action="{% url 'home' %}">
<input type="text" name="q" placeholder="Search Rooms...">
</form>
{% if request.user.is_authenticated %}
<a href="">Logout</a>
{% else %}
<a href="{% url 'login' %}">Login</a>
{% endif %}
<hr></hr>
{% if request.user.is_authenticated %}
<a href="{% url 'logout' %}">Logout</a>
{% else %}
<a href="{% url 'login' %}">Login</a>
{% endif %}
def logoutUser(request) :
logout(request)
return redirect('home')
path('logout/',views.logoutUser, name="logout"),
from django.contrib.auth.decorators import login_required
뷰 파일에 다음과 같은 라이브러리 임포트
@login_required(login_url='login')
업데이트, 딜리트, 크리에이트 에 위 코드 추가
뷰 파일
from django.http import HttpResponse
...
@login_required(login_url='login')
def updateRoom(request,pk) :
room = Room.objects.get(id=pk)
form = RoomForm(instance=room)
if request.user != room.host :
return HttpResponse('Your are not allowed here!!!') // 요거 요거
권한 있을 때만 버튼 나오게 됨
{% if request.user == room.host %}
<a href="{% url 'update-room' room.id %}">Edit</a>
<a href="{% url 'delete-room' room.id %}">Delete</a>
{% endif %}
def loginPage(request) :
if request.user.is_authenticated :
return redirect('home')
재사용
{% extends 'main.html' %}
{% block content %}
<div>
<form method="POST" action="">
{% csrf_token %}
<label>Username: </label>
<input type="text" name="username" placeholder="Enter Username">
<label>Password: </label>
<input type="password" name="password" placeholder="Enter Password">
<input type="submit" value="Login">
</form>
</div>
<div>
<form method="POST" action="">
{% csrf_token %}
<input type="submit" value="Register">
</form>
</div>
{% endblock content %}
def loginPage(request) :
page ='login'
...
context = {'page':page, }
return render(request, 'base/login_register.html',context)
...
def registerUser(request) :
page = 'register'
return render(request, 'base/login_register.html')
from django.contrib.auth.forms import UserCreationForm
...
def registerPage(request) :
page = 'register'
form = UserCreationForm()
if request.method == 'POST' :
form = UserCreationForm(request.POST)
if form.is_valid() :
user = form.save(commit=False) # 전처리
user.username = user.username.lower() # 대문자 소문자로 처리
user.save()
login(request,user)
return redirect('home')
else :
messages.error(request, 'An error occured during registration')
<p>Hello {{request.user}}</p>
{% extends 'main.html' %}
{% block content %}
<h1>{{room.name}}</h1>
<p>{{room.description}}</p>
<div class="comment-wrapper">
<h3>Conversation</h3>
<hr>
{% for message in room_messages %}
<div>
<small>@{{message.user}} {{message.created|timesince}} ago </small>
<p>{{message.body}}</p>
</div>
{% endfor %}
</div>
{% if request.user.is_authenticated %}
<div class="comment-form"></div>
<form method="POST" action="">
{% csrf_token %}
<input type = "text" name = "body" placeholder = "Wirte your Messge here">
</form>
{% endif %}
{% endblock content %}
def room(request,pk) :
room = Room.objects.get(id=pk)
room_messages = room.message_set.all().order_by('-created')
context = {'room':room,'room_messages':room_messages}
return render(request, 'base/room.html',context)
그리고
from .models import Room, Topic, Message
if request.method == 'POST' :
message = Message.objects.create()
댓글 만들었을 때
if request.method == 'POST' :
message = Message.objects.create(
user = request.user,
room = room,
body = request.POST.get('body'),
)
return redirect('room',pk=room.id)
일단 코드
{% extends 'main.html' %}
{% block content %}
<style>
.room-container{
display: grid;
grid-template-columns: 3fr 1fr;
}
</style>
<div class="room-container">
<div>
<h1>{{room.name}}</h1>
<p>{{room.description}}</p>
<div class="comment-wrapper">
<h3>Conversation</h3>
<hr>
{% for message in room_messages %}
<div>
<small>@{{message.user}} {{message.created|timesince}} ago </small>
<p>{{message.body}}</p>
</div>
<hr>
{% endfor %}
</div>
{% if request.user.is_authenticated %}
<div class="comment-form"></div>
<form method="POST" action="">
{% csrf_token %}
<input type = "text" name = "body" placeholder = "Wirte your Messge here">
</form>
{% endif %}
</div>
<div>
<h3>Participants</h3>
<hr>
</div>
</div>
{% endblock content %}
participants = models.ManyToManyField(User, related_name='participants', blank=True)
이거 주기
participants = room.participants.all()
context = {'room':room,'room_messages':room_messages,
'participants':participants}
{% for user in participants %}
<div>
<p>@{{user.username}}</p>
</div>
{% endfor %}
if request.method == 'POST' :
message = Message.objects.create(
user = request.user,
room = room,
body = request.POST.get('body'),
)
room.participants.add(request.user) # 이 부분을 통해 참여자 추가
return redirect('room',pk=room.id)
<div>
{% if request.user == message.user %}
<a href="{% url 'delete-message' message.id %}">Delete</a>
{% endif %}
<small>@{{message.user}} {{message.created|timesince}} ago </small>
<p>{{message.body}}</p>
</div>
@login_required(login_url='login')
def deleteMessage(request,pk) :
message = Message.objects.get(id=pk)
if request.user != message.user :
return HttpResponse('Your are not allowed here!!!')
if request.method == "POST" :
message.delete()
return redirect('home')
return render(request, 'base/delete.html', {'obj':message})
path('delete-message/<str:pk>/', views.deleteMessage, name="delete-message"),
1 3 1 그리드 형식
<div>
<h3>Recent Activity</h3>
<hr>
{% for message in room_messages %}
<div>
<small>@{{message.user}} {{message.created|timesince}}</small>
</div>
{% endfor %}
</div>
room_messages = Message.objects.all()
context = {'rooms':rooms, 'topics':topics, 'room_count':room_count,
'room_messages':room_messages,}
class Meta :
ordering = ['-updated','-created']
이 코드를 해당 클래스에 넣어주면 시간 빠른 순으로 나옴
{% for message in room_messages %}
<div>
<small>@{{message.user}} {{message.created|timesince}}</small>
<small>replied to "{{message.room}}"</small>
<p>{{message}}</p>
{% if request.user == message.user %}
<a href="{% url 'delete-message' message.id %}">Delete</a>
{% endif %}
</div>
{% endfor %}
room_messages = Message.objects.filter(Q(room__topic__name__icontains=q))
<a href="{% url 'user-profile' room.host.id %}">@{{room.host.username}}</a>
<small><a href="{% url 'user-profile' message.user.id %}">@{{message.user}}</a> {{message.created|timesince}}</small>
{% extends 'main.html' %}
{% block content %}
<style>
.profile-container{
display: grid;
grid-template-columns: 1fr 3fr 1fr;
}
</style>
<h1>{{user.username}}</h1>
<div class="profile-container">
<div>
{% include 'base/topics_component.html' %}
</div>
<div>
{% include 'base/feed_component.html' %}
</div>
<div>
{% include 'base/activity_component.html' %}
</div>
</div>
{% endblock content %}
path('profile/<str:pk>',views.userProfile, name="user-profile"),
def userProfile(request,pk) :
user = User.objects.get(id=pk)
rooms = user.room_set.all()
room_messages = user.message_set.all()
topics = Topic.objects.all()
context = {'user':user, 'rooms':rooms, 'room_messages': room_messages,
'topics':topics}
return render(request, 'base/profile.html',context)
메인 프로젝트 파일 내부에
static/styles/main.css
만들고
settings.py 에
STATICFILES_DIRS = [
BASE_DIR / 'static'
]
이거 만들어 주고
main.html 에
{% load static %}
<link rel="stylesheet" type='text/css' media="screen" href="{% static 'styles/main.css' %}">
이것을 줌으로 써 완성됨
이미지는
<img src="{% static 'images/grass.jpg' %}" alt="">
이런식으로 코딩하면 됨
class RoomForm(ModelForm) :
class Meta :
model = Room
field = '__all__' # 보여주고 싶은 것을 선책
exclude = ['host','participants'] # 안 보여주고 싶은 것
@login_required(login_url='login')
def createRoom(request) :
form = RoomForm()
if request.method == 'POST' :
form = RoomForm(request.POST)
if form.is_valid() :
room = form.save(commit=False) # 데이터 베이스에 추가
room.host = request.user
room.save()
return redirect('home') # url 에 이름 있어서 redirect 가능해짐
context = {'form':form}
return render(request, 'base/room_form.html', context)