Django01 프로젝트 - 동국푸드(2) urls 설정

|

결과물은 아래 링크에서 확인 가능합니다. 깃허브 결과물

이전 시간에 모델을 설정했으니, 그에 대해 url을 설정해준다.

프로젝트 urls 설정

먼저 프로젝트의 urls 파일에 아래 처럼 추가해주자. 뭔가 많아 보일테지만 일단은 입력해주자.

from django.contrib import admin
from django.urls import path, include
from django.views.generic.base import TemplateView
from django.conf import settings
from django.conf.urls.static import static

from store.models import Store

class HomePageView(TemplateView):

    template_name = 'home.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['store_list'] = Store.objects.filter(category='restaurant')[:1] | \
                                Store.objects.filter(category='bar')[:1] | \
                                Store.objects.filter(category='cafe')[:1]

        return context

urlpatterns = [
    path('board/', include('board.urls')),
    path('store/', include('store.urls')),
    path('admin/', admin.site.urls),
    path('accounts/', include('accounts.urls')),
    path('accounts/', include('django.contrib.auth.urls')),
    path('', HomePageView.as_view(), name='home'),
    path('about/', TemplateView.as_view(template_name='about.html'), name='about'),
]

if settings.DEBUG:
    import debug_toolbar
    urlpatterns += [path('__debug__/', include(debug_toolbar.urls))]
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

  • HomePageView는 최초 접속 시 보여줄 화면에 대해 정의한 것인데, 따로 둘데가 없기에 urls에 바로 정의해줬다.
  • accounts를 보면 두개가 있기에 의아할 수도 있는데, 첫번째는 내가 정의한 앱으로 가는 것이고, 두번째는 장고에서 기본 제공해주는 auth앱으로 들어가는 것이다. 장고가 기본적으로 비밀번호 변경, 찾기 같은 기능을 제공해주는데 이것을 이용해주려고 둔 것이다.
  • include를 사용해서 만약 ‘url/board’로 들어왔으면 나머지의 내용들은 board의 urls에서 참고하겠다는 의미이다.
  • 맨 마지막에는 DEBUG가 True일 때 작동들 하는 것이다. debug_toolbar에 대해서는 나중에 적도록 하겠다.

나머지 앱 urls 설정

지금은 views의 내용을 아직 만들지 않았기에 오류가 뜰테지만 일단은 입력해주자.

accounts

from django.urls import path
from . import views

app_name = 'accounts'
urlpatterns = [
	path('login/', views.UserLoginView.as_view(), name='login'),
	path('logout/', views.signout, name='logout'),
	path('signup/', views.UserSignUpView.as_view(), name='signup'),
	path('signup/done/', views.UserSignUpDoneView.as_view(), name='signup_done'),
	path('mypage/', views.MyPageV.as_view(), name='mypage'),
	path('checkuser/', views.check_user, name='check_user'),
	path('checknickname/', views.check_nickname, name='check_nickname'),
	path('finduser/', views.FindUser.as_view(), name='find_user')
]
  • 이름대로 login, logout, 회원가입, 마이페이지가 있다.
  • checkuser, checknickname: 회원가입 시 유저명, 닉네임 중복을 확인하는 용으로 쓴다. (ajax 활용)
  • finduser: 유저 검색 기능이다.

store

from django.urls import path
from . import views

app_name = 'store'
urlpatterns = [
    path('', views.StoreIndexView.as_view(), name='index'),
    path('category/<str:category>/', views.CategoryView.as_view(), name='category'),
    path('like/', views.like, name='like'),
    path('detail/<str:slug>/', views.StoreDetailView.as_view(), name='detail'),
    path('detail/<str:slug>/comment/', views.CommentListView.as_view(), name='comment'),
    path('detail/<str:slug>/comment/create/', views.comment_create, name='comment_create'),
    path('detail/<str:slug>/comment/update/<int:pk>/', views.comment_update, name='comment_update'),
    path('detail/<str:slug>/comment/delete/<int:pk>/', views.comment_delete, name='comment_delete'),
    path('create/', views.StoreCreateView.as_view(), name='store_add'),
    path('edit/<int:pk>/', views.StoreEditView.as_view(), name='store_edit'),
    path('delete/<int:pk>/', views.StoreDeleteView.as_view(), name='store_delete'),
]
  • 가게 리스트와 상세페이지, 가게글 CRUD,(superuser만) 댓글(CRUD)를 구현할 것이다.

board

from django.urls import path
from . import views

app_name = 'board'
urlpatterns = [
    path('', views.BoardIndex.as_view(), name='index'),
    path('detail/<str:slug>/', views.BoardDetail.as_view(), name='detail'),
    path('detail/<str:slug>/comment/create/', views.comment_create, name='comment_create'),
    path('detail/<str:slug>/comment/', views.CommentListView.as_view(), name='comment'),
    path('detail/<str:slug>/comment/create/', views.comment_create, name='comment_create'),
    path('detail/<str:slug>/comment/update/<int:pk>/', views.comment_update, name='comment_update'),
    path('detail/<str:slug>/comment/delete/<int:pk>/', views.comment_delete, name='comment_delete'),
    path('like/', views.like, name='like'),
    path('post/new/', views.BoardCreateV.as_view(), name='post_add'),
    path('post/edit/<int:pk>/', views.BoardUpdateV.as_view(), name='post_edit'),
    path('post/delete/<int:pk>/', views.BoardDeleteV.as_view(), name='post_delete'),
]
  • 게시판 리스트와 상세페이지, 게시판 CRUD,(superuser만) 댓글(CRUD)를 구현할 것이다.

Django01 프로젝트 - 동국푸드(1) 시작하기

|

결과물은 아래 링크에서 확인 가능합니다. 깃허브 결과물

Django01 프로젝트 - 동국푸드 시작하기

지금까지 패스트캠퍼스와 여러 튜토리얼을 보면서 Django에 대해 어느정도 지식을 쌓아뒀지만, 아직까지 나만의 프로젝트를 만들어 본적이 없었다. 개발자가 되기 위해서 중요한 것은 뭐든 만들어 보자. 인거 같다. 그렇기에 첫 번째 프로젝트를 시작해 보려고 한다.

  • 프로젝트명: 동국푸드
  • 설명: 필자는 현재 동국대에 재직자 전형으로 재학중이다. 나름대로 대학생활을 즐기면서 여러 음식집들을 방문하여 친구들과 가게들에 대한 평을 해봤었고, 이런 계기로 가게들을 설명하는 자유 커뮤니티를 만들어 보고자 한다.

준비하기

  • 프로젝트 생성: 예전에 사용했던 프로젝트 위에서 사용해서 mysite로 시작했다. django-admin startproject mysite

  • 앱 생성: 내가 생각한 앱들은 회원정보, 가게소개, 게시판 정도로 생각했다.
    • 회원정보: 로그인, 로그아웃, 회원가입을 구현하기
    • 가게소개: 동국대 주변 음식집에 대한 정보를 소개, 좋아요 기능 구현 예정
    • 게시판: 일반 자유게시판, 좋아요 기능 구현 예장 django-admin startapp accounts, store, board 앱 별로 다 실행해준다.
  • 모델 생성: 각 앱들에 대한 모델들을 정의해줬다.

    accounts

    Django에서 제공해주는 User와 1대1 관계를 통해 추가로 받고 싶은 정보들을 설정했다. (현재는 AbstractUser로 변경했기에 참고 정도로만 봐주자.)

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    nickname = models.CharField(max_length=30, null=True, verbose_name='닉네임',)
    phone_number = models.CharField(max_length=30, null=True, verbose_name='전화번호',)

    class Meta:
        verbose_name = '프로필'
        verbose_name_plural = '프로필'

    def __str__(self):
        return self.user.username

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

현재 accounts는 AbstractUser로 변경했다.

from django.db import models
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    email = models.EmailField(max_length=254, unique=True, verbose_name='이메일')
    nickname = models.CharField(max_length=30, unique=True, verbose_name='닉네임')
    phone_number = models.CharField(max_length=30, unique=True, verbose_name='전화번호')

store

가게와 메뉴에 대한 정보를 관리한다.

class Store(models.Model):
    name = models.CharField(max_length=50, verbose_name="가게명")
    slug = models.SlugField('SLUG', unique=True, allow_unicode=True, help_text='one word for alias')
    location = models.CharField(max_length=100, blank=True, verbose_name="위치")
    phone_number = models.CharField(max_length=30, blank=True, verbose_name="연락처")
    description = models.TextField(blank=True, verbose_name="설명")
    store_image = models.ImageField(blank=True, upload_to="store/store_pic")
    created_dt = models.DateTimeField(auto_now_add=True)
    modified_dt = models.DateTimeField(auto_now=True)
    likes = models.IntegerField(verbose_name='좋아요', default=0)
    tags = TaggableManager(blank=True)

    class Meta:
        verbose_name = '가게'
        verbose_name_plural = '가게'
        ordering = ['likes', ]

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('store:detail', args=[self.slug])

class Menu(models.Model):
    store = models.ForeignKey(Store, on_delete=models.CASCADE, verbose_name="가게명")
    name = models.CharField(max_length=50, verbose_name="메뉴")
    description = models.CharField(max_length=50, blank=True, verbose_name="설명")
    food_image = models.ImageField(blank=True, upload_to="store/menu_pic")

    class Meta:
        verbose_name = '메뉴'
        verbose_name_plural = '메뉴'

    def __str__(self):
        return "{} - {}".format(self.store, self.name)

board

게시판을 관리하는 앱이다.

from django.db import models
from django.contrib.auth.models import User

class UserBoard(models.Model):
    title = models.CharField(max_length=50, blank=True, verbose_name='제목')
    writer = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='작성자')
    created_date = models.DateTimeField(auto_now_add=True)
    content = models.TextField(verbose_name='내용')
    hits = models.IntegerField(null=True, blank=True, verbose_name='좋아요')

    def __str__(self):
        return '유저:{}, 제목:{}'.format(self.writer, self.title)

    def board_save(self):
        self.save()

    class Meta:
        ordering = ['-created_date']
        verbose_name = '게시판'
        verbose_name_plural = '게시판'

settings 파일 설정

INSTALLED_APPS += [
    'accounts',
    'board',
    'store',
]
# 유저 모델을 새로 사용하는거기 때문에 아래를 추가해준다.
AUTH_USER_MODEL = 'accounts.User'

# 로그인 필요 시, 이동되는 페이지
LOGIN_URL = '/accounts/login/'
# 로그인 성공 시, 리다이렉트 url
LOGIN_REDIRECT_URL = 'home'
# 로그아웃 성공 시, 리다이렉트 url
LOGOUT_REDIRECT_URL ='home'
# 웹페이지에 사용할 정적파일의 최상위 URL 경로

STATIC_URL = '/static/'
STATIC_DIR = os.path.join(BASE_DIR, 'static')

# 정적파일이 위치한 경로들을 지정하는 설정 항목, 이 설정 통해서 앱 밑에 static 파일 만들고 그런듯 함
STATICFILES_DIRS = [
    STATIC_DIR,
]
# collectstatic 시 파일 위치
STATIC_ROOT = os.path.join(BASE_DIR, '.static_root')

# 유저들이 업로드한 미디어 파일들에 대한 설정
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

여기까지 했으면 아래의 명령어를 마지막으로 입력해주자.

python manage.py makemigrations python manage.py migrate

첫번째는 모델에 대해서 DB에 반영해줄 내용들을 만들어주고, 두번째로 DB에 적용시켜주는 것이다.

앞으로 이를 기반으로 홈페이지를 제작하고 알게된 것을 포스팅 해보고자 한다.

200608-200614_TIL

|

6월 8일 (월)

  • jQuery Ajax에 대해 수강하였다. 내가 만드는 프로젝트에 좋아요 기능을 구현할 때 사용해보려 한다.

6월 9일 (화)

  • Django UpdateView, DeleteView에 대해 알아보고 정리하였다.
  • 자바스크립트를 브라우저 말고 터미널에서 테스트 해보려고 node js를 설치해보았다.

6월 10일 (수)

  • jQuery를 통해 비밀번호 확인 스크립트를 구현해보았다.
  • 파이썬 웹 프로그래밍이라는 책을 구입해서 읽는 중이다.

6월 11일 (목)

  • 파이썬 웹 프로그래밍 책의 태그기능을 구현해보았다. 내 프로젝트에 적용해봐야겠다.

200601-200607_TIL

|

6월 1일 (월)

  • 달팽이 배열에 대해 풀어봤다. for문에 대해서 더 깊이 생각할 필요를 느꼈다. 알고리즘도 차근차근 풀어봐야겠다.

  • 패스트캠퍼스 django 2 강의를 AWS배포빼고 다 들었다. 설명이 부족해서 아쉬움이 많지만, 활용할 수 있는 지식이 많음을 느꼈다. 조만간 세 번째 강의도 들어야겠다.

6월 2일 - 7일

  • javascript에 대해 공부 중, 만드는 사이트에서 좋아요 기능을 구현하기 위해 공부중이다.
  • 학교과제와 동아리 보고서 준비중이다.

200525-200531_TIL

|

5월 25일 (월)

  • jquery를 사용시 slim 버전을 사용하면 안되겠다. ajax를 지원하지 않는다고 한다.

이번주는 학교 과제로 생략…