▶️ Django
[▶️Front-end] Bootstrap으로 화면 구성(회원 가입, 로그인, 로그아웃)
main 페이지에 추후 수정이 필요한 내용 중, 좋아요&싫어요 버튼 기능 구현 과정을 담은 글이에요.
Article 모델만 완성한 글입니다!


지금의 메인 페이지예요.
폴라로이드 사진으로 된 곳에 유저가 만든 모델을 불러오도록 하고, 좋아요&싫어요 버튼이 추가될 거예요.
이번 글에는 게시글 겉에 표현될 생성된 모델 사진, 유저 id, 작업 id, 좋아요&싫어요를 구현하는
Back-end 로직 내용을 다룰 거예요.
구현 시작!
구현하기에 앞서서, 좋아요 기능은 M:N이기 때문에 DB 관리를 어떻게 할 것이고,
좋아요 수는 어떻게 카운팅 할지, 모델은 어떻게 구성할지 고민을 했어요. 🤔
⚙️ branch 생성
# article branch 생성
$ git branch article
# article branch로 이동
$ git switch article
⚙️ articles app 생성
# articles app
$ python manage.py startapp articles
⚙️ core/settings.py
# core/settings.py
INSTALLED_APPS = [
...
# Create app list
...
"articles", # 메인 화면에 있는 글 관리 앱
]
⚙️ core/urls.py
# core/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
...
path("articles/", include('articles.urls')),
]
⚙️ articles/models.py
더보기
# articles/models.py
from django.db import models
from django.conf import settings
from workspace.models import MeshModel
import random
"""
3월 5일까지
게시글 겉에 보일 것들 :
- 생성된 모델 사진
- 유저 id
- 작업 id
- 좋아요, 싫어요 버튼
3월 5일 이후로 할 것들 ⬇️
게시글 상세 내용 :
(왼편)
- 생성된 모델 사진
- 타이틀 (모델 프롬프트)
- 태그
- 모델 시드 (pk)
- 모델 프롬프트 (복사 버튼)
- 텍스쳐 프롬프트 (복사 버튼)
(오른편)- 추후 추가할지 말지 결정하자.
- 유저 프로필
- 팔로우 버튼
- 유저의 다른 모델 작품 리스트(미리보기, 모델 프롬프트) -> 추후
"""
# article 모델
"""
아래 내용을 포함하고 있어요.
user id, job id, title, model&texture_prompt, model_seed, image, likes, dislikes, created_at, tag
model_seed : 랜덤으로 1 ~ 2147483648 숫자 범위 내에서 부여됩니다.
-> def save, def generate_unique_model_seed로 저장 및 유니크 관리
"""
class Article(models.Model):
user_id = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="articles"
) # 유저 아이디
job_id = models.ForeignKey(MeshModel, on_delete=models.CASCADE) # 작업 아이디
title = models.CharField(max_length=255, default="model_prompt") # 게시글 제목
model_prompt = models.TextField()
texture_prompt = models.TextField()
model_seed = models.IntegerField(unique=True)
image = models.ImageField(upload_to="article/image/") # 모델 이미지
likes = models.ManyToManyField(
settings.AUTH_USER_MODEL, related_name="like_articles"
) # 좋아요
dislikes = models.ManyToManyField(
settings.AUTH_USER_MODEL, related_name="dislike_articles"
) # 싫어요
created_at = models.DateTimeField(auto_now_add=True) # 생성 시간
tags = models.CharField
# model_seed는 정한 범위값 내에서 랜덤으로 부여(중복 허용 X)
def save(self, *args, **kwargs):
if not self.model_seed: # 값이 없을 때만 생성
self.model_seed = self.generate_unique_model_seed()
super().save(*args, **kwargs)
def generate_unique_model_seed(self):
while True:
number = random.randint(1, 2147483648) # 원하는 범위 설정
if not Article.objects.filter(model_seed=number).exists():
return number
⚙️ articles/urls.py
더보기
# articles/urls.py
from django.urls import path
from .views import ArticleList
app_name = "articles"
urlpatterns = [
path("articlelist/", ArticleList, name="articlelist"), # 게시물 목록
]
⚙️ articles/views.py
더보기
# articles/views.py
from django.shortcuts import render
# 게시글 목록 보기
def ArticleList(request):
return render(request, "main.html")
마무리
Front는 이전에 만들었던 main.html을 쓸 거라서 추가하진 않았어요.
하지만 수정은 하였죠!
<수정한 내용>
<!-- Image Gallery (Right) -->
<div class="col-md-9">
<div class="row">
{% for article in article_list %}
<div class="col-md-4">
<div class="card">
<div class="card-img-top">
<i class="fas fa-image fa-5x" style="color: lightgray;"></i>
</div>
<div>
<form method="post" action="{% url "articles:articlelike" article.id "like" %}">
{% csrf_token %}
<button type="submit">❤️</button>
</form>
<form method="post" action="{% url "articles:articlelike" article.id "dislike" %}">
{% csrf_token %}
<button type="submit">🤨</button>
</form>
</div>
<div class="card-body">
<p class="card-content">User ID : {{ article.user_id }}
Job ID : {{ article.job_id}}</p>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<main.html>
더보기
{% extends "base.html" %}
{% block content %}
<div class="wrapper">
<div class="container-fluid">
<div class="row">
<!--Left button-->
<div class="col-md-3">
<button class="btn-custom w-100" onclick="location.href='/workspace/create/'">
Create to text ✏️ <i class="fas fa-file"></i>
</button>
<button class="btn-custom w-100">Create to image 📷<i class="fas fa-image"></i></button>
</div>
<!-- Image Gallery (Right) -->
<div class="col-md-9">
<div class="row">
{% for article in article_list %}
<div class="col-md-4">
<div class="card">
<div class="card-img-top">
<i class="fas fa-image fa-5x" style="color: lightgray;"></i>
</div>
<div>
<form method="post" action="{% url "articles:articlelike" article.id "like" %}">
{% csrf_token %}
<button type="submit">❤️</button>
</form>
<form method="post" action="{% url "articles:articlelike" article.id "dislike" %}">
{% csrf_token %}
<button type="submit">🤨</button>
</form>
</div>
<div class="card-body">
<p class="card-content">User ID : {{ article.user_id }}
Job ID : {{ article.job_id}}
</p>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<style>
.container {
margin-top: 20px;
}
.card {
margin-top: 15px;
margin-bottom: 20px;
padding: 10px;
}
.card-img-top {
background-color: #f0f0f0; /* Placeholder gray color */
height: 200px;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
}
.card-title {
font-size: 16px;
text-align: left;
}
/* 왼쪽 버튼 설정*/
.btn-custom {
background-color: white;
color: black;
border: 1px solid #ced4da;
border-radius: 5px;
margin-top: 15px;
margin-bottom: 0px;
padding: 8px 12px;
display: flex;
justify-content: space-between;
align-items: center;
}
.btn-custom:hover {
background-color: #e9ecef; /* Light gray on hover */
}
.btn-custom i {
margin-left: 5px; /* Space between text and icon */
}
.placeholder-image {
width: 100%;
height: 200px; /* Adjust as needed */
background-color: #f0f0f0;
border: 1px solid #ddd;
display: flex;
justify-content: center;
align-items: center;
color: #aaa;
margin-bottom: 10px; /* Added spacing between images */
}
.placeholder-image svg {
width: 50%; /* Adjust size as needed */
height: 50%;
}
</style>
{% endblock %}
'👥 최종 팀 프로젝트(250227~250331) > 구현 과정 ▶️' 카테고리의 다른 글
[▶️Back-end] 메인 페이지에 좋아요, 싫어요 버튼 기능 구현 3차 完 (0) | 2025.03.06 |
---|---|
[▶️Back-end] 메인 페이지에 좋아요, 싫어요 버튼 기능 구현 2차 (0) | 2025.03.06 |
[▶️Front-end] Bootstrap으로 화면 구성(회원 가입, 로그인, 로그아웃) (0) | 2025.03.03 |
[▶️Back-end] Auth 기능 구현하기(회원 가입, 로그인, 로그아웃) 2차 完 (0) | 2025.03.03 |
[▶️Back-end] Auth 기능 구현하기(회원 가입, 로그인, 로그아웃) 1차 (0) | 2025.03.02 |