컴굥일지
[Django Study 14] Projectapp Implementation 본문
반응형
[ProjectApp 구현]
Create / Detail / List View 를 구현한다.
(Update / Delete는 구현하지 않는다.
Success_url to related Project (프로젝트 만들면 이후 이어질 페이지 정하기)
Login_required to CreateView (최소한 로그인은 해야 프로젝트를 할 수 있게 하자)
Model : title / description / image / created_at
python manage.py startapp projectapp
settings.py에 projectapp 추가
urls.py
#projectapp/urls from django.urls import path from projectapp.views import ProjectListView, ProjectCreateView, ProjectDetailView app_name = 'projectapp' urlpatterns = [ path('list/', ProjectListView.as_view(), name='list'), path('create/', ProjectCreateView.as_view(), name='create'), path('detail/<int:pk>', ProjectDetailView.as_view(), name='detail'), ]
views.py
#projectapp/views.py from django.contrib.auth.decorators import login_required from django.shortcuts import render # Create your views here. from django.urls import reverse from django.utils.decorators import method_decorator from django.views.generic import CreateView, DetailView, ListView from django.views.generic.list import MultipleObjectMixin from articleapp.models import Article from projectapp.forms import ProjectCreationForm from projectapp.models import Project from subscribeapp.models import Subscription @method_decorator(login_required, 'get') @method_decorator(login_required, 'post') class ProjectCreateView(CreateView): model = Project form_class = ProjectCreationForm template_name = 'projectapp/create.html' def get_success_url(self): return reverse('projectapp:detail', kwargs={'pk': self.object.pk}) class ProjectDetailView(DetailView, MultipleObjectMixin): model = Project context_object_name = 'target_project' template_name = 'projectapp/detail.html' paginate_by = 25 def get_context_data(self, **kwargs): project = self.object user = self.request.user if user.is_authenticated: subscription = Subscription.objects.filter(user=user, project=project) else: subscription = None object_list = Article.objects.filter(project=self.get_object()) return super(ProjectDetailView, self).get_context_data(object_list=object_list, subscription=subscription, **kwargs) class ProjectListView(ListView): model = Project context_object_name = 'project_list' template_name = 'projectapp/list.html' paginate_by = 25
models.py
#projectapp/models.py from django.db import models # Create your models here. class Project(models.Model): image = models.ImageField(upload_to='project/', null=False) title = models.CharField(max_length=20, null=False) description = models.CharField(max_length=200, null=True) created_at = models.DateTimeField(auto_now=True) def __str__(self): return f'{self.pk} : {self.title}'
forms.py
from django.forms import ModelForm from projectapp.models import Project class ProjectCreationForm(ModelForm): class Meta : model = Project fields = {'image', 'title', 'description'}
HTML 생성
create.html
<!--projectapp/templates/create.html--> {% extends 'base.html' %} {% load bootstrap4 %} {% block content %} <div style="text-align: center; max-width: 500px; margin: 4rem auto"> <div class="mb-4"> <h4>Create Project</h4> </div> <form action="{% url 'projectapp:create' %}" method="post" enctype="multipart/form-data"> {% csrf_token %} {% bootstrap_form form %} <input type="submit" class="btn btn-dark rounded-pill col-6 mt-3"> </form> </div> {% endblock %}
detail.html
{% extends 'base.html' %} {% block content %} <div> <div style="text-align: center; max-width: 500px; margin: 4rem auto 1.5rem auto;"> <img src="{{ target_project.image.url }}" alt="" style="height: 12rem; width: 12rem; border-radius: 20rem; margin-bottom: 2rem; object-fit: cover;"> <h2 style="font-family: 'NanumSquareB'"> {{ target_project.title }} </h2> <h5> {{ target_project.description }} </h5> </div> <div class="text-center mb-5"> {% if user.is_authenticated %} {% if not subscription %} <a href="{% url 'subscribeapp:subscribe' %}?project_pk={{ target_project.pk }}" class="btn btn-primary rounded-pill px-4"> Subscribe </a> {% else %} <a href="{% url 'subscribeapp:subscribe' %}?project_pk={{ target_project.pk }}" class="btn btn-dark rounded-pill px-4"> Unsubscribe </a> {% endif %} {% endif %} </div> <div> {% include 'snippets/list_fragment.html' with article_list=object_list %} </div> </div> {% endblock %}
list.html
{% extends 'base.html' %} {% load static %} {% block content %} <style> .container { padding: 0; margin: 0, auto; } .container div { display: flex; justify-content: center; align-items: center; border-radius: 1rem; } .container img { width: 7rem; height: 7rem; object-fit: cover; border-radius: 1rem; } </style> {% if project_list %} <div class="container"> {% for project in project_list %} <a href="{% url 'projectapp:detail' pk=project.pk %}"> {% include 'snippets/card_project.html' with project=project %} </a> {% endfor %} </div> <script src="{% static 'js/magicgrid.js' %}"></script> {% else %} <div class="text-center"> <h1>No Projects YET!</h1> </div> {% endif %} {% include 'snippets/pagination.html' with page_obj=page_obj %} <div style="text-align: center"> <a href="{% url 'projectapp:create' %}" class="btn btn-dark rounded-pill mt-3 mb-3 px-3"> Create Project </a> </div> {% endblock %}
[MultipleObjectMixin을 통한 ProjectApp 마무리]
project와 article을 연결해주는 작업을 해 줄 것이다
- articleapp의 models.py에서 아래 코드 추가한 후
project = models.ForeignKey(Project, on_delete=models.SET_NULL, related_name='article', null=True)
views.py로 가서 project를 추가해준다
- terminal에 ‘python manage.py makemigration’ 작성
- projectapp의 views.py로 가서 detailview에서 MultipleObjectionMaxin 추가한 후 아래 코드도 추가
paginate_by = 25
def get_context_data(self, **kwargs):
object_list = Article.objects.filter(project=self.get_object())
return super(ProjectDetailView, self).get_context_date(object_list=object_list, **kwargs)
- 앱에 종속되어 있지 않는 template에 list_pragment 파일을 생성한 후 아래 코드 작성 (articleapp의 list.html 복사해와서 내용 고치는 정도)
{% load static %}
<style>
.container {
padding : 0;
margin: 0, auto;
}
.container a{
width: 45%;
max-width: 250px;
}
.container div {
display: flex;
justify-content: center;
align-items: center;
border-radius: 1rem;
}
.container img{
width: 100%;
border-radius: 1rem;
}
</style>
{% if article_list %}
<div class="container">
{% for article in article_list %}
<a href="{% url 'articleapp:detail' pk=article.pk}">
{% include 'snippets/card.html' with article=article %}
</a>
</div>
<script src="(% static 'js/magicgird.js" %}></script>
<% else %>
<div class="text-center">
<h1>No Articles YET!</h1>
</div>
{% endif %}
{% include 'snippets/pagination.html' with page_obj=page_obj %}
<div style="text-align center">
<a href="{% url 'articleapp:create' %}" clss="btn btn-dark rounded-pull col-3 mt-3 mb-3 px-2">
Create Article
</a>
</div>
- 그리고 projectapp의 detail.html로 가서 아래 코드 추가
<div>
{% include 'scrippts/list_pragment.html' with article_list=object_list %}
</div>
위 과정을 account app 파일에서 똑같이 적용해준다
[출처] 작정하고 장고! Django Pinterest 따라만들기 : 바닥부터 배포까지
섹션 8. Projectapp Implementation (40강 ~ 41강)
반응형
'프로그래밍 강의 > Django' 카테고리의 다른 글
[Django Study 16] Django Wrap-up (0) | 2022.05.15 |
---|---|
[Django Study 15] Subscribeapp Implementation (0) | 2022.05.14 |
[Django Study 13] Mobile Responsive Layout (0) | 2022.05.08 |
[Django Study 12] Commentapp Implementation (0) | 2022.04.27 |
[Django Study 11] Articleapp Implementation (0) | 2022.04.26 |
Comments