[django] django로 갠홈 만들어서 heroku로 배포하기

2021. 9. 2. 21:25

결과물: 

https://pyoumg.herokuapp.com/

 

nunnu - main

세영(pyoumg) 2000/03/16일상을 그리는 컴퓨터공학과 학부생 홈페이지명 'NunNu'에는 그림그리는것이 즐거운 생활을 지속해 나가고 싶다는 마음이 담겨있습니다:) 최종 업데이트 21/08/18

pyoumg.herokuapp.com

 


 

 

 

스터디로 공부했던 책은 이거! 따라하면서 만들 수 있어 좋았다

https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=259491574 

 

Do it! 장고 + 부트스트랩 파이썬 웹 개발의 정석

블로그 웹 사이트를 만드는 실습을 진행하면서 웹 개발 기초부터 블로그 개발, 배포, 운영까지 한 번에 다룬다. 이 과정에서 HTML, CSS, 자바스크립트부터 부트스트랩, 파이썬 웹 프레임워크 장고(D

www.aladin.co.kr

 

 

 

스터디에서 따라하며 블로그 사이트를 만든 후, 이걸 응용한 개인 사이트를 만들어서 배포하기로 했다.

지난번에 얼레벌레 아무것도 모른 채 만들었던 개인 홈페이지를 방학 때 친구와 django 스터디를 하며 다시 만들어보았다.

2021.01.27 - [컴퓨터] - [bootstrap studio] wix로 만들었던 홈페이지를 bootstrap studio로 다시 만들어본 후기

 

[bootstrap studio] wix로 만들었던 홈페이지를 bootstrap studio로 다시 만들어본 후기

*구구절절 주의* 중학생 때(2014? 2015? 처음 만든 날짜 찾아보려고 했는데 못찾았음..ㅠㅠ) 그림들 정리한다고 wix로 홈페이지를 만들었었다. (그 당시에 wix가 짱 유행했음.. 물론 지금도!) 그때 만든

kumonoueno.tistory.com

 

 

책에서는 blog, single_pages의 두 모듈을 생성했고,

나는 description,painting,single_pages의 세 모듈을 생성했다

책과 같이 부트스트랩을 사용했다.

urlpatterns = [
    path("admin/", admin.site.urls),
    path("painting/", include("painting.urls")),
    path("main/", include("description.urls")),
    path("markdownx/", include("markdownx.urls")),
    path("", include("single_pages.urls")),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

painting/2021: 2021년에 그린 그림들 나열

main/2021: 2021 연말정산

그 외: single_pages에 처리

 

로 url을 나누었다

footer와 navbar을 모듈화 했다

1. description

흔히 '연말정산'이라고 하는 페이지를 만들 때 사용되는 모듈이다.

결론적으로 사진 하나만 띄워져서 single_pages로 해도 괜찮았을 것이지만

처음 구상했을 때는 밑의 설명도 있어서 별도의 모듈로 했다 (설명 없앤 이유는 너무 흑역사라서)

class Year(models.Model):
    name = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(max_length=200, unique=True, allow_unicode=True)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return f"year/{self.slug}/"


class Description(models.Model):
    # image = models.ImageField(upload_to=f"description/images/description/", blank=True)
    image = models.CharField(blank=True, null=True, max_length=150)
    year = models.ForeignKey(Year, null=True, blank=True, on_delete=models.SET_NULL)
    text = MarkdownxField()

    def __str__(self):
        return f"[{self.year}]"

    def get_content_markdown(self):
        return markdown(self.text)

class Year는 slug가 있어서 url에 사용할 수 있도록 했다.

지금 보니까 get_absolute_url()잘못 쓴듯... base.html에서 써먹은 부분이 없어서 지워도 될 듯 하다

 

image는 ImageField가 아닌 CharField인데, 이유는 heroku에서는 ImageField를 사용했을 때 정상적으로 출력되지 않기 때문이다.

 

markdown이 있는 이유도 밑의 설명(text)때문이다(그러나 실제로 쓸 때는 지움)

urlpatterns = [
    path("<slug:slug>/", views.des_page),
]


2. painting

 

그림을 나열하는 페이지인데, lightbox를 사용했다.

https://lokeshdhakar.com/projects/lightbox2/

 

Lightbox2

Examples Two individual images Four image set Getting started Download a zip of the latest release (or any previous one) from the Github Releases page. Or install using npm: npm install lightbox2 --save Open up the zip file and take a peek at the barebones

lokeshdhakar.com

 

show more 버튼을 클릭하면 버튼이 사라지고 밑에 숨겨진 그림이 더 나온다

def year_page(request, slug):
    year = Year.objects.get(slug=slug)
    post_list = Post.objects.filter(year=year)

    return render(
        request,
        "painting/post_list.html",
        {
            "year": slug,
            "post_list": post_list[:6],
            "post_num": Post.objects.filter(year=year).count(),
            "post_list_plus": post_list[6:],
        },
    )


class PostList(ListView):
    model = Post

    def get_context_data(self, **kwargs):
        context = super(PostList, self).get_context_data()
        context["year"] = Year.objects.all()

        return context

CBV를 사용하여 post_list.html을 자동으로 사용할 수 있다

class Year(models.Model):
    name = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(max_length=200, unique=True, allow_unicode=True)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return f"/painting/{self.slug}/"


class Post(models.Model):
    year = models.ForeignKey(Year, null=True, blank=True, on_delete=models.SET_NULL)
    # image = models.ImageField(upload_to=f"painting/images/", blank=True)
    image = models.CharField(blank=True, null=True, max_length=150)
    thumbnail = models.CharField(blank=True, null=True, max_length=150)

    ordering = "pk"

    def __str__(self):
        return f"{self.image[-25:]} [{self.year}] ({self.pk})"

url을 확인하기 위해서 __str__()에서 self.image를 좀 길게 잡았다(다 출력하기엔 너무 길다)

 

3. single_pages

기타 단일 페이지를 여기에 모아둠(그래봤자 3개)

 

urlpatterns = [
    path("", views.about_me),
    path("comics/2016-2018", views.comic),
    path("prj/2016-2018", views.prj),
]

 

웹폰트는 눈누에서 복사함!

https://noonnu.cc/

 

눈누 - 상업용 무료한글폰트 사이트

상업적으로 이용할 수 있는 무료 한글 폰트를 모아 놓은 사이트 눈누

noonnu.cc

 


heroku로 배포

 

책에서는 django-> docker이지만 heroku를 사용한 이유

1. 무료로 계속 사용가능 

2. 상대적으로 간편

 

이 두가지이다

 

https://tutorial-extensions.djangogirls.org/ko/heroku

 

헤로쿠(Heroku) 배포하기

 

tutorial-extensions.djangogirls.org

여기에 나오는 대로 따라하면 쉽게 할 수 있다. 마이그레이션에서 에러가 나는 경우는 지우고 다시 해보면 된다.

 

heroku 무료버전은 30분 이상 접속하지 않으면 sleep한다는 단점이 있는데, 밑의 사이트에서 주기적으로 깨워주는 기능이 있다.

https://kaffeine.herokuapp.com/

 

Kaffeine

Remove your app from Kaffeine. http:// .herokuapp.com Decaf App not found Your app has been removed.

kaffeine.herokuapp.com

 

그리고 위에서 heroku에서는 ImageField가 안되길래 플러그인 Cloudinary를 사용했다

 

  

BELATED ARTICLES

more