1. admin.ModelAdmin -> list_display 사용하여 admin 게시판 리스트 양식 바꾸기
https://www.kite.com/python/docs/django.contrib.admin.ModelAdmin.list_display
1) 관리자 페이지에서 blog앱에 보이는 게시판 양식을 변경해보자
- 기존: title만 노출 -> id, title, count_text 세 가지가 노출되도록 변경해보자
- blog/admin.py 파일에 코딩
from django.contrib import admin
from .models import Post
class PostAdmin(admin.ModelAdmin):
list_display = ['id', 'title', 'count_text']
list_display_links = ['title']
def count_text(self, obj):
return '{}글자'.format(len(obj.text))
count_text.short_description = 'text 글자수'
# Register your models here.
admin.site.register(Post, PostAdmin)
2) 결과화면
- ID필드, TEXT글자수 필드가 추가된 것을 볼 수 있다.
(단 디비에 기존에 없던 필드인 TEXT글자수 필드가 저장이 되는 건 아님을 주의. 그저 보여지는 화면에서만 나오는 것)
3) 참고문서
https://docs.djangoproject.com/en/2.0/ref/models/fields/#field-types
2. 필드 추가 및 삭제
>> 필드 추가
1) Post테이블에 test필드 추가하기 위해 모델 클래스에 필수 필드를 추가
2) 기존 모델 클래스에 필수 필드를 추가하여 makemigrations 수행
- 필수 입력 필드를 추가하므로, 기존 Row들에 필드를 추가할 때, 어떤 값으로 채워 넣을지 묻는다.
선택 1) 지금 값을 입력
선택 2) 모뎅 클래스를 수정하여 디폴트 값을 제공
3) 0002_post_test.py라는 migrations파일 생성된 것 확인
4) migration 적용 현황
- x표시가 없으면 아직 DB에 반영이 안됐단 의미
5) migration 적용
- DB에 반영
6) 결과화면
- DB에 반영된 모습
- Post게시판에 Test 컬럼에 anonymous값이 추가되어 보이는 모습
7) 지정 migration의 SQL 내역
- 실제 디비에서 실행되는 sql실행문 보여주는 명령어
>> 필드 제거
1) models.py에서 test필드 주석처리
2) remove migrations 파일 생성
3) migration 적용 현황
- x표시가 없으면 아직 DB에 반영이 안됐단 의미
4) migration 적용
- DB에 반영
5) 지정 migration의 SQL 내역
- 실제 디비에서 실행되는 sql실행문 보여주는 명령어
** 참고 문서 자료
https://south.readthedocs.io/en/latest/
3. URL Routing - Django URLConf 설정하기
1) post_list라는 함수(def) 만들어 요청(request)을 받아서 직접 문자열로 HTML형식 응답(response) 하기
- blog/views.py
from django.shortcuts import render
from django.http import HttpResponse
# Post 목록
def post_list(request):
name = 'Django'
return HttpResponse('''
<h2>Post List</h>
<p>웰컴 {name}!!!</p>
<p>{content}<p/>'''.format(name=name, content=request.content_type))
2) http://127.0.0.1:8000/ 요청이 오면 post_list를 보여준다.
- blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
# loacalhost:8080/
path('', views.post_list, name='post_list')
]
3) mydjango/urls.py 에서 blog/urls.py를 불러와 포함시킨다.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls'))
]
4) 결과화면
4. View
1) view의 역할
- 애플리케이션의 '로직'을 포함하며 모델에서 필요한 정보를 받아와서 템플릿에 전달하는 역할을 한다.
- Model과 Template을 연결하는 역할을 한다.
- URLConf에 매핑된 Callable Object
: 첫번째 인자로 HttpRequest인스턴스를 받는다. 반드시 HttpResponse인스턴스를 리턴해야한다.
2) blog/views.py
- post_list 함수를 만들어 요청을 넘겨받아 render메서드를 호출한다.
- 함수는 호출하여 받은 blog/post_list.html템플릿을 보여준다.
from django.shortcuts import render
from django.http import HttpResponse
# Post 목록
def post_list(request):
#name = 'Django'
# return HttpResponse('''
# <h2>Post List</h>
# <p>웰컴 {name}!!!</p>
# <p>{content}<p/>'''.format(name=name, content=request.content_type))
return render(request, 'blog/post_list.html')
5. Template
1) Template의 역할
- 정보를 일정한 형태로 표시하기 위해 재사용 가능한 파일을 말함.
- Django의 template 양식은 HTML을 사용한다.
- 템플릿은 blog/templates/blog 디렉토리에 저장한다.
- 엔진 자체는 templates밑에 있는걸 한번에 찾기 때문에 blog건지, board건지 몰름, 그러니까 teamplates밑에 또 폴더이름을 써줘야함
2) blog/templates/blog/post_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog List</title>
</head>
<body>
<h2>Blog List</h2>
<p>request.user : {{request.user}}</p>
<p>request.content_type : {{request.content_type}}!!!</p>
<p>Http Method : {{request.method}}</p>
</body>
</html>
3) 결과화면
4) 참고 문서
https://docs.djangoproject.com/en/1.11/ref/request-response/
6. QuerySet
1) QuerySet이란?
- DB로부터 데이터를 읽고, 필터링을 하거나, 정렬을 할 수 있따.
2) 쿼리셋을 사용하기 위해 먼저 python shell을 실행한다.
3) 모든 객체 조회하기
- 모든 객체를 조회하기 위해 all()함수를 사용한다.
4) 객체 생성하기
- User(사용자) 모델의 인스턴스를 가져와 전달해준다.
- 객체를 저장하기 위해 create() 함수를 사용한다.
5) 필터링하기
- 원하는 조건으로 데이터를 필더링 한다. filter() 괄호 안에 원하는 조건을 넣어주면 된다.
- 이전에 만들어논 publish함수를 사용해보자
- 가져온 Post인스턴스를 publish()메서드를 이용하여 게시한다.
- Sample title에 published_date가 저장되어 조건에 맞는 것으로 변해 조회에 나타난 것을 볼 수 있다.
6) 정렬하기
- 작성일 기준으로 오름차순 / 내림차순 으로 정렬하기
7) 참고 문서 자료
https://docs.djangoproject.com/en/3.0/ref/models/querysets/
7. View에서 동적 데이터 생성하기
1) view의 수정
- view는 DB에서 저장되는 Model에서 정보를 가져올 때 쿼리셋(Query Set)을 사용하며, 템플릿에 전달하는 역할을 한다.
- 게시일을 기준으로 과거에 자겅한 글을 필터링하여 정렬하여 글 목록 가져오기
- blog/views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.utils import timezone
from .models import Post
# Post 목록
def post_list(request):
#name = 'Django'
# return HttpResponse('''
# <h2>Post List</h>
# <p>웰컴 {name}!!!</p>
# <p>{content}<p/>'''.format(name=name, content=request.content_type))
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
2) Template의 수정
- Template에서는 view에서 저장한 posts변수를 받아와서 HTML에 출력한다.
- 변수의 값을 출력하려면 중괄호를 사용한다.
- {% for %}와 {% endfor %} 사이에서 목록의 모든 객체를 반복하여 출력함
- | linebreaksbr 같이 파이프 문자( | )를 사용하여, 블로그 글 텍스트에서 행이 바뀌면 문단으로 변환하여 출력한다.
- blog/templates/blog/post_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog List</title>
</head>
<body>
<h2>Blog List</h2>
<p>request.user : {{request.user}}</p>
<p>request.content_type : {{request.content_type}}!!!</p>
<p>Http Method : {{request.method}}</p>
{% for post in posts %}
<div>
<p>published : {{post.published_date}}</p>
<h1><a href="">{{post.title}}</a></h1>
<p>{{post.text|linebreaksbr}}</p>
</div>
{% endfor %}
</body>
</html>
3) 결과화면
4) 참고 문서
https://docs.djangoproject.com/en/3.0/ref/templates/builtins/
8. Template Engine문법
1) Variables
• {{ first_name }}
• {{ mydict.key }} : dict의 key에 attr 처럼 접근
• {{ myobj.attr }}
• {{ myobj.func }} : 함수 호출도 attr 처럼 접근. 인자 있는 함수 호출 불가
• {{ mylist.0 }} : 인덱스 접근도 attr 처럼 접근
2) Django Template Tag
• {% %} 1개 쓰이기도 하며, 2개 이상이 조합되기도 함.
• 빌트인 Tag가 지원되며, 장고앱 별로 커스텀 Tag 추가 가능
block, comment, csrf_token, extends, for, for ... empty, if, ifchanged, include, load, lorem, now, url, verbatim, with 등
3) block tag
• 템플릿 상속에서 사용
• 자식 템플릿이 오버라이딩 할 block 영역을 정의
• 자식 템플릿은 부모가 정의한 block에 한해서 재 정의만 가능. 그 외는 모두 무시됩니다.
{% block block-name %}
block 내에 내용을 쓰실 수 있습니다.
{% endblock %}
4) Comment Tag : 템플릿 주석, 렌더링되지 않음
{% comment "Optional note" %}
Server comment
{% endcomment %}
5) csrf_token tag
• Cross Site Request Forgeries를 막기 위해 CSRF Middleware가 제공
• 이는 HTML Form의 POST요청에서 CSRF토큰을 체크하며, 이때 CSRF토큰이 필요
• csrf_token tag를 통해 CSRF토큰을 발급받을 수 있습니다.
<form method="POST" action="">
{% csrf_token %}
<input type="text" name="author" />
<textarea name="message"></textarea>
<input type="submit" />
</form>
9. css - 정적(static)파일 처리하기
1) css파일 작성
- static 디렉토리 안에 css디렉토리를 만들고 blog.css 파일 작성
h1 a {
color:#f8ffa6;
font-family:'Lobster';
}
body{
padding-left:15px;
}
2) html파일 작성
<!DOCTYPE html>
{% load static %}
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Blog List</title>
{% load static %}
<link rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext"
type="text/css">
<link rel="stylesheet" href="{% static 'css/blog.css' %}">
</head>
<body>
<h2>Blog List</h2>
<p>request.user : {{request.user}}</p>
<p>request.content_type : {{request.content_type}}!!!</p>
<p>Http Method : {{request.method}}</p>
{% for post in posts %}
<div>
<p>published : {{post.published_date}}</p>
<h1><a href="https://naver.com">{{post.title|title}}</a></h1>
<p>{{post.text|linebreaksbr}}</p>
</div>
{% empty %}
<div>요청하신 Post가 존재하지 않습니다. </div>
{% endfor %}
{% comment "Optional note" %}
Server comment
{% endcomment %}
<!-- html Client Comment -->
</body>
</html>
3) 결과화면
10. boot-strap
1) 부트스트랩 페이지 이다. 참고바람
2) CDN(Content Delivery Network)
- 아래와 같이 링크로 되어있는것을 CDN이라한다.
CDN이란.... 사용자가 리소스를 다운로드할 수 있는 대체 서버노드를 제공하여 작동한다. 이러한 노드는 전 세계에 퍼져있기 떄문에 지연 시간 감소로 인해 컨텐츠의 빠른 응답과 다운로드 시간을 제공함으로써 사용자에게 더 가까운 전략적 이점을 제공한다.
- 해당 링크를 들어가보면 다음과 같이 필요한 명령어들이 압축되어 있는 파일인 것을 볼 수 있다.
3) HTML 파일
<!DOCTYPE html>
{% load static %}
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Blog List</title>
{% load static %}
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
<!-- google lobster font-->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext"
type="text/css">
<!-- 개발자 정의 CSS-->
<link rel="stylesheet" href="{% static 'css/blog.css' %}">
</head>
<body>
<div class="page-header">
<h1><a href="/">Django Blog</a></h1>
</div>
<div class="content container">
<div class="row">
<div class="col-md-8">
{% for post in posts %}
<div class="post">
<div class="date">
<p>published : {{post.published_date}}</p>
</div>
<h1><a href="https://naver.com">{{post.title|title}}</a></h1>
<p>{{post.text|linebreaksbr}}</p>
</div>
{% empty %}
<div>요청하신 Post가 존재하지 않습니다. </div>
{% endfor %}
</div>
</div>
</div>
{% comment "Optional note" %}
Server comment
{% endcomment %}
<!-- html Client Comment -->
</body>
</html>
4) CSS 파일
.page-header{
background-color: #ff9400;
margin-top: 0;
padding: 20px 20px 20px 40px;
}
.page-header h1, .page-header h1 a, .page-header h1 a:visited, .page-header h1 a:active{
color: #ffffff;
font-size: 36pt;
text-decoration: none;
}
h1, h2, h3, h4{
font-family:'Lobster', cursive;
}
.content{
margin-left:40px;
}
.date{color: #828282;}
.save{float:right;}
.post-from textarea, .post-form input{width:100%;}
.top-menu, .top-menu:hover, .top-menu:visited{
color: #ffffff;
float:right;
font-size:26pt;
margin-right:20px;
}
.post{margin-bottom:70px;}
.post h1 a, .post h1 a:visited{color:#000000;}
5) 결과화면
11. favicon 적용하기
1) 사이트로 들어간다.
https://favicon.io/favicon-generator/
2) 원하는 문구, 배경색, 폰트사이즈 등등을 설정 후 다운로드 클릭
3) 원하는 파일에 저장
4) 압축을 풀고 favicon.io파일을 복사한다.
5) 이미지는 변하지 않는 파일이므로 static폴더 아래에 붙혀넣는다.
6) <link rel="shortcut icon" href="{%static 'favicon.ico'%}"> 로 불러온다.
7) 적용이 완료된 모습
'Python > Django' 카테고리의 다른 글
django 와 mongodb연동 (0) | 2020.08.17 |
---|---|
페이지네이션 (0) | 2020.08.11 |
Django 댓글기능 추가 (0) | 2020.08.07 |
Django 템플릿 상속 / 게시판 만들기 (0) | 2020.08.06 |
Django설치 및 설정 & 간단한 게시판 만들기 (0) | 2020.08.04 |