완숙의 블로그

[Django] Week 4_3 Blog & Portfolio Project _1 본문

Programing Language/Web_Django

[Django] Week 4_3 Blog & Portfolio Project _1

완숙 2019. 2. 26. 21:05

자 이번에는 속도감있게! 저번까지 했던 것들을 복습해보자!

 

  1. VS code 켜기

     

  2. 가상환경 들어가기

    $ source myvenv/bin/activate
    

     

  3. 프로젝트 만들기

    $ django-admin startproject secondproject(프로젝트이름)
    

     

  4. 프로젝트 이름과 해당 파일 경로 안의 폴더이름이 겹치니 상위 프로젝트이름을 second 로 바꿔줌

     

  5. 내가 만들고 싶은 프로젝트파일 안으로 들어가기

    $ ls
    $ cd second
    

     

  6. 앱 만들기

    $ python manage.py startapp blog
    

     

  7. 앱을 만들었으니 settings.py 에 가서 등록을 해주자.

    # settings.py
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'blog.apps.BlogConfig', # 이녀석
    ]
    

     

  8. 이 앱은 어떤 역할까지하는 앱이냐면 블로그화면을 띄워주는 것까지 하므로 templates 폴더를 만든다.

 

  1. templates 안에 홈화면을 보여줘야되니 home.html을 만든다.

 

  1. 그런데 home화면을 보여주기위한 함수는 views.py에 작성하기 때문에 함수를 작성해주자.

    # views.py
    from django.shortcuts import render
    
    def home(request):
        return render(request, 'home.html')
    

     

  2. 그런데 어떤 url로 접근했을 때 이 함수가 실행되는지를 알려줘야하니 urls.py 로 가서 알려주자.

    이 때, 우리가 해야할 것은, 어떤 경로로 들어갔을 때, views에 있는 함수를 실행 시켜야 하니, views.py 를 가져오자.

    # urls.py
    import blog.views # 가져오기!
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', blog.views.home, name = "home"), # 빈 url이면, views.py의 home을 불러와라!
    ]
    

     

  3. 중간확인! 서버켜보자.

    $ python manage.py runserver
    

     

  4. 잘 떴다면! 이녀석을 일단 꾸며보자.

     

  5. 여기서, 부트스트랩을 사용할텐데, 이걸 사용하기 위해서 CDN을 사용하자.

     

  6. 그러기 위해서는 <head> 태그안에 넣어줘야하니,

    <!-- home.html -->
    <head>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    
    </head>
    <body>
    <h1>여기는 홈</h1>
    
    </body>
    
    

    home.html 을 이렇게 바꿔주자.

     

  7. CDN을 설치했으니, 이제 가져와서 쓰기만 하면 된다.

    먼저 원하는 NAV bar를 가져와 붙여넣자.

     

  8. 잘 붙여졌다면 NAV bar 색을 바꿔보자.

    부트스트랩 아래를 잘 읽어보면 색을 어떻게 바꿀 수 있는지 나와있다.

    보통 클래스를 다르게 사용하거나, 배경색을 지정하는 다른 파라미터로 조절할 수 있다.

     

  9. Model 설정!

    models.py 에 내가 어떤 정보를 담을 것인지 class로 선언을 해준다고 했다.

    나는 Blog 라는 모델을 만들거고, 이 안에는 제목, 발간날짜, 내용 정도를 넣을 듯 하다.

    기본적으로 django에서 model은 sqlite를 사용하므로 해당하는 DB의 문법을 사용해야 한다.

    # models.py
    from django.db import models
    
    class Blog(models.Model):
        title = models.CharField(max_length = 200)
        pub_date = models.DateTimeField('date published!')
        body = models.TextField()
    

     

  10. 자 들어올 데이터를 다 정의해줬으니, 내가 이번에는 manage.py 한테, 나 모델 만들었어! 라고 알려줘야한다.

    $ python manage.py makemigrations
    

     

  11. 그 다음은 작동시켜줘야 한다.

    $ python manage.py migrate
    

     

  12. 이 데이터를 넣기 위해서는 admin 사이트에서 넣어줄수 있는데, 이걸 하려면 admin 계정이 있어야 한다.

    이런 중심적인 것은 manage.py 가 대부분 관리한다.

    $ python manage.py createsuperuser
    

     

  1. 계정을 만든 뒤에는, 이 모델을 admin에다가 알려줘야 한다. /admin 에서 수정을 할 수 있기 때문이다.

    # admin.py
    from django.contrib import admin
    from .models import Blog 	# models.py에서 Blog 라는 클래스를 불러와라
    
    admin.site.register(Blog)	# admin이라는 site에 Blog라는 클래스를 등록해라.
    

     

  2. 서버를 돌려보자!

    $ python manage.py runserver
    

     

  3. /admin에 들어간 후 blog 객체들을 만드면

    2019-02-25 3 56 12

    이렇게 뜬다. 여기서 우리는 블로그 객체가 생김에 따라 id값을 부여하고 싶다!

     

  4. 이 과정을 하고 싶으면 , models.py에 함수를 하나 만들어 주면 되는데,

    from django.db import models
    
    # Create your models here.
    
    
    class Blog(models.Model):
        title = models.CharField(max_length=200)
        pub_date = models.DateTimeField('date published')
        body = models.TextField()
    
        def __str__(self):
            return self.title
    

    __str__ 은 특수 메쏘드인데 객체의 문자열 표현을 돌려주기로 되어있다.

     

  5. 그럼 이제 모델까지 만들었으니, 이걸 보여줄 차례!

    보여줘야 하므로, templates 폴더에 details.html 을 만들어주고, views.py 에 필요한 것들을 함수로 정의해주자.

    # views.py
    from django.shortcuts import render
    from .models import Blog			# 모델에 있는 Blog객체를 가공해서 보여줄 것
    
    def home(request):
        blogs = Blog.objects			# 블로그 객체를 다 가져온다!(1번글, 2번글, 3번글)
        								# Queryset
        return render(request, 'home.html', {'blogs':blogs}) # 세번째 인자로 받아주자.
    

     

  6. 자, 여기까지하면, 어떤 정보를 가공하여 보여줄 지에 대해 끝났다.

    그럼 이제 보여주는 일이 남았다. 이 home으로 정의된 함수안에서의 내용을 접근하려면, 딕셔너리로 접근해서 html로 넘겨주면 된다.

    <!-- home.html -->
    
    ~
    bootstrap code
    ~
    
    {blogs}
    

    그런데 이렇게만 표현하면, 내가 원하는 녀석들이 안나온다. 우리는 이 하나의 객체에 대해 정의된 instance 변수값이 필요하다.

    또, 각각의 객체에 대해 이 과정을 반복 해주어야 한다.

    따라서 반복분이 일단 필요하다.

     

  7. 딕셔너리 키 값을 어떻게 모두 받아오고 for문을 사용할 수 있는지 기억해보자.

    <!-- home.html -->
    {% for blog in blogs.all %}
    	<h1>제목 : {{ blog.title }}</h1>
    	<p>시간 : {{ blog.pub_date }}</p>
    	<p>내용 : {{ blog.body }}</p>
    {% endfor %}
    

     

  8. 여기까지 하고 서버를 켜서 결과를 확인하면, 너무 글이 왼쪽에 붙어있다는 사실을 발견할 수 있다.

    그러니까 bootstrap에 가서 이 전체 결과를 큰 녀석 안에 담아주도록 하자. 이럴때 containers 안에 담아주면 된다.

    <!-- home.html -->
    <div class="container">
      {% for blog in blogs.all %}
        <h1>제목 : {{ blog.title }}</h1>
        <p>시간 : {{ blog.pub_date }}</p>
        <p>내용 : {{ blog.body }}</p>
      {% endfor %}
    </div>
    

     

  9. 자 이제 home.html 에 각 블로그 글을 띄웠다. 이번엔 내용 끝에 more을 달고, 이걸 누르면 detail 페이지에 들어가도록 만들어 보자.

     

  10. 일단 먼저, detail에 들어가더라도 NAVbar는 고정되기 원하니, 복사해서 넣어두자.

     

  11. 이제, more를 누른다면, 해당하는 url로 가고, 이것은 urls.py에서 적용해줘야한다.

    둘째로, 이 경로를 만들어주었다면, 이 경로로 왔을 때, 어떻게 정보를 처리해줄것인지를 관리하는 views.py에 가서 함수를 작성해준다.

    셋째로, 가공된 정보를 내가 원하는 양식에 맞추어 detail.html에 작성해준다.

     

  12. 첫째, urls.py로 가자.

    # urls.py
    from django.contrib import admin
    from django.urls import path
    import blog.views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', blog.views.home, name = "home"),
        path('blog/<int:blog_id>', blog.views.detail, name = "detail"), # 여기!
    ]
    

    우리는 경로를 눌렀을때, blog/숫자 와 같은 형식의 url로 접속하길 바란다. 여기서, 숫자에 대응되는 값이 선언이 안되어 있으므로, 우리가 설정해줘야 한다.

    그런데, 숫자이므로 정수형으로 int를 선언해주고, 또 이 변수의 이름은 blog_id로 잡았다.

    이 url로 접근했을 때, 어디로 정보를 처리할 것인지는 views.py의 detail함수가 담당할 것이니, 중간 파라미터를 blog.views.detail 로 잡아주자.

    이름은 detail 로 하자.

     

  13. 그럼 이제 정보를 처리하는 views.py로 가자.

    그럼, 기존과 같이 함수 정의 후, 입력값을 받을 텐데, 이번에는 요청값만 들어오는 것이 아니고,

    path로 부터 정의된 blog_id 역시 받아서 사용해야한다!

     

    그 다음에, details 라는 변수에 이 넘겨받은 인수를 가지고 해당하는 blog 객체를 가져와야 한다.

    이 때, get_object_or_404 를 사용한다.

    이녀석을 사용하기 위해 import를 해주자.

     

    그런데 이 것도 결국에는 함수이다. 그렇기 때문에 인자를 넣어줄 건데,

    1. 어떤 객체를 받아올 것인지
    2. 어떤 것을 기준으로 가져올 것인지

    상식적으로 두가지가 필요하다.

    이때 2번을 결정해주는 파라미터의 이름을 pk 라 했다.

     

    우리는 Blog객체에서 blog_id를 기준으로 불러올 것이기 때문에 pk = blog_id 가 될 것이다.

     

    그리고 나서 이 결과값을 반환해주면 되는데, home 함수와 비슷하다.

    # views.py
    from django.shortcuts import render, get_object_or_404 # import 하기
    from .models import Blog # 동일한 폴더를 말할 때 . 을 사용, 거기서 Blog라는 클래스를 불러와라
    
    def home(request):
        blogs = Blog.objects 
        return render(request, 'home.html', {'blogs':blogs}) 
    
    def detail(request, blog_id):
        details = get_object_or_404(Blog, pk = blog_id)
        return render(request, 'detail.html', {'details':details})
    

     

  14. 자 여기까지 하면 이제 내가 링크를 누르면 해당 링크에 숫자를 달고,

    이 숫자를 기반으로 해서 model에서 내 블로그 객체를 불러오며,

    이것을 딕셔너리형으로 html에서 불러올 수 있게 만들었다.

    그런데 아직 해결이 안된 부분이, 링크를 누르면 이 부분이 해결안되었다.

    링크를 누르는 것은 home.html 에서 하니, 이쪽으로 가보자.

     

  15. 어, 그런데 내가 원하는 것은 내용이 100자까지만 출력되기를 원하는데 지금 models.py에 들어가면,

    그렇게 정의해놓지 않았다. 이걸 어떻게 해결할까?

     

  16. 이것은 models.py 에 들어가서 다른 함수를 만들어줌으로써 해결할 수 있었는데,

    # models.py
    from django.db import models
    
    # Create your models here.
    
    
    class Blog(models.Model):
        title = models.CharField(max_length=200)
        pub_date = models.DateTimeField('date published')
        body = models.TextField()
    
        def __str__(self):
            return self.title
        def summary(self):
            return self.body[:100] # 이 부분!
    

    이렇게 summary라는 함수를 하나 만들어주고, 이 녀석을 실행시키면

    default 값이었던 body가 자기자신의 body를 0~100까지의 인덱스만 가져오도록 수정된 녀석을 반환한다.

     

  17. 그럼 이 값이 표시되는 것은 home.html 이니까 이쪽으로 가서 이제 37에서 말했던 링크설정까지 해주자.

    어, 근데 링크는 어떻게 넘겨줄까?

    이 링크를 누르게 되었을 때, 어디로 넘어가는지 생각해보면, urls.py 로 넘어간다.

    즉 python script에서 사용해야 하므로 우리는 템플릿 태그를 사용해서 넘겨줘야 한다.

    이 때 path들의 이름을 우리는 다 명시를 해줬기 때문에 생각보다 쉽게 넘겨줄 수 있다.

    {% url 'detail'%} 이렇게. url detail 이름으로 가!

    그런데, 이 상태라면, 내가 클릭한 링크의 대한 번호가 넘겨지지 않은 상태이다.

    이 링크를 클릭했을 때, 이 객체에 대한 어떤 정보를 넣어주어야 하냐면,

    이 객체에 대한 id 를 넘겨줘야 할 것이다.

    그리고 이 정보를 path 에서는 blog_id로 넘겨 받게 된다!

     

    해당 for문에서 사용하는 변수 blog는 blogs 로 받았던 녀석중 하나를 가지고 있는 녀석이다.

    그러니 이녀석의 id를 path의 blog_id로 넘겨주면 되겠다!

    따라서, {% url 'detail' blog.id%} 로 적어주자.

    <!-- home.html -->
    <body>
        <div class="container">
          <h1>여기는 홈</h1>
          {% for blog in blogs.all %}
            <h1>제목 : {{ blog.title }}</h1>
            <p>시간 : {{ blog.pub_date }}</p>
            <p>내용 : {{ blog.body }} <a href = "{% url 'detail' blog.id %}"> ...more </a></p>
          {% endfor %}
        </div>
    </body>
    
    

     

  18. 서버를 돌려보면 잘 작동이 될 것이야!

     

  19. 그럼 이제 detail.html 만 만들어주면 끝!

    views.py 에서 detail 함수에 반환값으로 details 라는 딕셔너리를 넘겨주었으니

    여기에 접근해서 우리가 원하는 제목, 내용과 같은 것들을 가져오면 되겠다!

    <!-- detail.html -->
    <div class = "container">
        <h1> 자세한 본문 내용입니다. </h1>
        <br><br>
        <h1> 제목 : {{details.title}} </h1>
        <p> 작성 날짜 : {{details.pub_date}} </p>
        <p> 자세한 본문 : {{details.body}} </p>
    </div>
    

     

  20. 자 이제 디자인을 해볼까~

    부트스트랩으로 가자!

    title을 검색해보자.

    <!-- bootstrap code -->
    <div class="card" style="width: 18rem;">
      <div class="card-body">
        <h5 class="card-title">Card title</h5>
        <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
        <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
        <a href="#" class="card-link">Card link</a>
        <a href="#" class="card-link">Another link</a>
      </div>
    </div>
    

    이녀석을 긁어봐왔다!

     

  21. 이제 내가 필요한 부분을 바꾸어서 이부분에 넣어주면 될것이당

    저 자체를 넣으면 <div class="card" style="width: 18rem;"> 에서 width가 결정되어서 나올 것이다.

    우리는 container 안에서 쭈욱 확장된 상태로 출력되기를 원하기 때문에 width를 지워주자.

    another link도 필요없으니 지워주자.

    <!-- home.html -->
    {% for blog in blogs.all %}
    <br>
      <div class="container">
          <!-- <h1>제목 : {{ blog.title }}</h1>
          <p>시간 : {{ blog.pub_date }}</p>
          <p>내용 : {{ blog.body }} <a href = "{% url 'detail' blog.id %}">...more</a></p> -->
          <div class="card">
              <div class="card-body">
                <h5 class="card-title">{{ blog.title }}</h5>
                <h6 class="card-subtitle mb-2 text-muted">{{ blog.pub_date }}</h6>
                <p class="card-text">{{ blog.body }}</p>
                <a href="{% url 'detail' blog.id %}" class="card-link">...more</a>
                
              </div>
            </div>
      </div>
    {% endfor %}
    

     

  22. 끝났습니다!

Comments