(Django 기초) ProjectApp 시작

Posted by : at

Category : Django



$ python manage.py startapp projectapp
# pragmatic\settings.py

# ...

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'bootstrap4',
    'profileapp',
    'accountapp',
    'articleapp',
    'commentapp',
    'projectapp',
]

# ...
# pragmatic\urls.py

# ...

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('accountapp.urls')),
    path('profiles/', include('profileapp.urls')),
    path('articles/', include('articleapp.urls')),
    path('comments/', include('commentapp.urls')),
    path('projects/', include('projectapp.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# projectapp\urls.py

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'), 
]
# projectapp\models.py

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)
# projectapp\forms.py

class ProjectCreationForm(ModelForm):
    class Meta:
        model = Project
        fields = ['image', 'title', 'description']
# projectapp\views.py

@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 ProjectListView(ListView): 
    model = Project 
    context_object_name = 'project_list' 
    template_name = 'projectapp/list.html' 
    paginate_by = 25


class ProjectDetailView(DetailView):
    model = Project
    context_object_name = 'target_project'
    template_name = 'projectapp/detail.html'
<!-- projectapp\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 'projectapp/snippets/card.html' with project=project %} 
        </a> 
      {% endfor %} 
      </div> 
      <script src="{% static 'js/magic-grid.js' %}"></script> 
    {% else %} 
      <div style="text-align:center;"> 
          <h1>No Project YET!</h1> 
      </div> 
    {% endif %} 
    {% include 'projectapp/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 %}
<!-- projectapp\detail.html -->

{% extends 'base.html' %}

{% block content %}

<div>
  <div style="text-align: center; max-width: 500px; margin: 4rem 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: 'NnumSquareB'">
      {{ target_project.title }}
    </h2>
    <h5 style="margin-bottom: 3rem;">
      {{ target_project.description }}
    </h5>
  </div>
</div>

{% endblock %}
<!-- projectapp\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 %}
<!-- projectapp\snippets\card.html -->
<div style="display: block; text-align: center;"> 
  <img src="{{ project.image.url }}" alt=""> 
  <h5 class="mt-2" style="font-family: 'NanumSquareB'"> 
    {{ project.title | truncatechars:3 }} 
  </h5> 
</div>
<!-- projectapp\snippets\pagination.html -->
<div style="text-align: center; margin; 1rem 0;">
    {% if page_obj.has_previous %}
    <a href="{% url 'projectapp:list' %}?page={{ page_obj.previous_page_number }}" class="btn btn-secondary rounded-pill">
        {{ page_obj.previous_page_number }}
    </a>
    {% endif %}
    <a href="{% url 'projectapp:list' %}?page={{ page_obj.number }}" class="btn btn-secondary rounded-pill active">
        {{ page_obj.number }}
    </a>
    {% if page_obj.has_next %}}
    <a href="{% url 'projectapp:list' %}?page={{ page_obj.next_page_number }}" class="btn btn-secondary rounded-pill">
        {{ page_obj.next_page_number }}
    </a>
    {% endif %}
</div>
<!-- header.html -->
<div class="pragmatic_header">
    <div>
        <h1 class="pragmatic_logo">Pragmatic</h1>
    </div>
    <div>
        <a href="{% url 'articleapp:list' %}" class="pragmatic_header_nav">
            <span>Articles</span>
        </a>
        {% if not user.is_authenticated %}
        <a href="{% url 'accountapp:login' %}?next={{ request.path }}">
            <span>login</span>
        </a> class=pragmatic_header_nav
        <a href="{% url 'accountapp:create' %}" class="pragmatic_header_nav">
            <span>SignUp</span>
        </a>
        {% else %}
        <a href="{% url 'accountapp:logout' %}?next{{ request.path }}" class="pragmatic_header_nav">
            <span>logout</span>
        </a>
        <a href="{% url 'accountapp:detail' pk=user.pk %}" class="pragmatic_header_nav">
            <span> MyPAge</span>
        </a>
        {% endif %}
    </div>
</div>
$ python manage.py makemigrations
$ python manage.py migrate
$ python .\manage.py runserver


About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links