Question과 Choice모델 클래스 는 1:N관계로 이루어져 있고 , 서로 외래키로 연결되어 있습니다.
4.1.6 Question및 Choice를 한 화면에서 변경하기
Model.py
from django.contrib import admin from polls.models import Question, Choice # Register your models here.
''' class QuestionAdmin(admin.ModelAdmin): fields = ['pub_date','question_text'] #필드 순서 변경 ''' class ChoiceInline(admin.StackedInline): model = Choice extra = 2
class QuestionAdmin(admin.ModelAdmin): fieldsets = [ ('None',{'fields':['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] #Choice 모델 클래스 같이 보기
class QuestionAdmin(admin.ModelAdmin): fields = ['pub_date','question_text'] #필드 순서 변경 ''' #class ChoiceInline(admin.StackedInline): class ChoiceInline(admin.TabularInline): model = Choice extra = 2
class QuestionAdmin(admin.ModelAdmin): fieldsets = [ ('None',{'fields':['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] #Choice 모델 클래스 같이 보기 list_display = ('question_text','pub_date')#렠코드 리스트 컬럼 지정
class ChoiceInline(admin.TabularInline): model = Choice extra = 2
class QuestionAdmin(admin.ModelAdmin): fieldsets = [ ('None',{'fields':['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] #Choice 모델 클래스 같이 보기 list_display = ('question_text','pub_date')#렠코드 리스트 컬럼 지정 list_filter = ['pub_date']
from django.contrib import admin from polls.models import Question, Choice # Register your models here.
''' class QuestionAdmin(admin.ModelAdmin): fields = ['pub_date','question_text'] #필드 순서 변경 ''' #class ChoiceInline(admin.StackedInline): class ChoiceInline(admin.TabularInline): model = Choice extra = 2
class QuestionAdmin(admin.ModelAdmin): fieldsets = [ ('None',{'fields':['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline] #Choice 모델 클래스 같이 보기 list_display = ('question_text','pub_date')#렠코드 리스트 컬럼 지정 list_filter = ['pub_date'] search_fields = ['question_text']
Out[14]: <QuerySet [<Question: What's new?>, <Question: What is you hobby ?>, <Question: What do you like best ?>, <Question: Where do you live ?>, <Question: What's new ? >]>
In [8]: Question.objects.filter(pub_date__year= current_year)
Out[8]: <QuerySet [<Question: What's new?>, <Question: What is you hobby ?>, <Question: What do you like best ?>, <Question: Where do you live ?>, <Question: What's new ? >]>
Namespace: urls.py파일의 include()함수 또는 app_name변수에 정의한 이름공간(namespace)이름
View-name:urls.py파일에서 정의한 url패턴이름
argN: 뷰 함수에서 사용하는 인자로 ,없을 수도 있고 여러 개인 경우 빈칸으로 구분함
{% with %}태그
{% load %}
{%load somelibrary package.otherlibrary %}
4.3.4 템플릿 주석
{# greeting #}hello
{# {% if foo %} bar{% else %} #}
{% comment “Optional note” %}
<p>Commented out text here</p>
{% endcomment %}
4.3.5 HTML 이스케이프
Name = “<b>username”
Hello, {{ name }}
Hello, <b>username =>약점 xss Cross Site Scripting 공격이 이루어집니다.
XSS공격이란 Cross-Site Scripting는 사이트 간 스크립팅 공격이라고도 합니다. 웹 사이트의 취약점을 공격하는 방식 중의 하나로 , 웹 사이트 관리자가 아닌 일반 사용자라도 시도할 수 있는 공격 방법입니다. 주로 여러 사용자가 보게 되는 전자 게시판에 악성 스크립트가 담긴 글을 올리는 형태로 이루어집니다. 이 취약점은 웹 애플리케이션이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 경우 나타냅니다.
<<
>>
‘'
“"
&&
4.3.6 템플릿 상속
Title 블록, sidebar블록, content블록 3개입니다.
{% block %}
4.4 폼 처리하기
4.4.1 html에서의 폼
getpost 방식
4.4.2 장고의 폼 기능
데이터가 없는 폼을 언바운드 unbound폼이라고 하며 , 언바운드 폼은 렌더링 되어 사용자에게 보옂루 때 비어있거나 디폴트 값으로 채워집니다.
바운드 bound폼은 제출된 데이터를 갖고 있어서 데이터의 유효성 검사를 하는데 사용됩니다.
4.4.3 폼 클래스로 폼 생성
참고로 장고의 폼 클래스는 모든 필드에 대해 유효성 검사 루틴을 실행시키는 is_valide()메소드 를 갖고 있습니다. 이 메소드가 호출되어 유효성 검사를 하고 , 그 결과 만일 모든 필드가 유효하다면 is_valid()메소드는 다음과 같은 2가지 일을 합니다.
True를 반환합니다.
폼 데이터를 cleaned_data속성에 넣습니다.
4.4.4 뷰에서 폼 클래스 처리
뷰 함수
Form.is_valie():
Get_name()
4.4.5 폼 클래슬르 템플릿으로 변환
{{ from.as_table }}
{{ from.as_p }}
{{ from.as_ul }}
4.5 클래스형 뷰
뷰 callable
4.5.1 클래스형 뷰의 시작점
As_view()진입 메소드의 역할은 크ㄹ래스의 인스턴스를 생성하고 , 그 인스턴스의 dispatch()메소드를 호출합니다.
Dispatch()메소드는 요청을 검사해서 GET, POST등의 어떤 HTTP메소드로 요청되었는지를 알아낸 다음 ,인스턴스 내에서 해당 이름을 갖는 메소드로 요청을 중계해줍니다.
HttpResponseNotAllowed 익셉션을 발생시킵니다.
4.5.2 클래스형 뷰의 장점 – 효율적인 메소드 구분
4.5.3 클래스형 뷰의 정점 – 상속 기능 가능
4.5.4 클래스형 제네릭 뷰
제네릭 뷰 generic view
4.5.5 클래스형 뷰에서 폼 처리
4.6 로그 남기기
4.6.1 로거
4.6.2 핸들러
4.6.3 필터
4.6.4 포맷터
4.6.5 로거 사용 및 로거 이름 계층화
mysite/settings.py
# logging LOGGING = { 'version' :1, # 기존의 로깅 설정을 비활성화 할 것인가? 'disable_existing_loggers' : False, # 핸들러 # 로그 레코드로 무슨 작업을 할 것인지 정의 # 여러 핸들러 정의 가능 'handlers':{ 'console':{ 'class': 'loggingStreamHandler' }, }, # 로거 # 로그 레코드 저장소 # 로거를 이름별로 정의 'loggers': { 'mylogger' :{ 'handlers' : ['console'], 'level' :'INFO' } } }
사용법
Import logging
#settngs.py파일에서 설정된 로거를 취득함
Logger = logging.getLogger(‘mylogger’)
4.6.6장고의 default 로깅 설정
4.6.7 장고의 로깅 추가 사항 정리
로깅 설정 – 디폴트 설정 유지
# logging LOGGING = { 'version' :1, # 기존의 로깅 설정을 비활성화 할 것인가? 'disable_existing_loggers' : False, # 포맷터 # 로그 레코드는 최종적으로 텍스트로 표현됨 # 이 텍스트의 포맷 형식 정의 # 여러 포맷 정의 가능 'formatters': { 'verbose': { 'format': '[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s', 'datefmt': '%d/%b/%Y %H:%M:%S' }, 'format2': { 'format': '%(levelname)s %(message)s' }, }, # 핸들러 # 로그 레코드로 무슨 작업을 할 것인지 정의 # 여러 핸들러 정의 가능 'handlers':{ #'console':{ #'class': 'loggingStreamHandler' #}, # 로그 파일을 만들어 텍스트로 로그레코드 저장 'file': { 'level': 'DEBUG', 'class': 'logging.FileHandler', 'filename': os.path.join(BASE_DIR, 'logs','mysite.log'), 'formatter': 'verbose', }, # 콘솔(터미널)에 출력 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'format2', } }, # 로거 # 로그 레코드 저장소 # 로거를 이름별로 정의 'loggers': { 'django' :{ 'handlers' : ['file'], 'level' :'DEBUG' }, 'mysite':{ 'handlers' : ['file'], 'level' : 'DEBUG', } } }
Settings.py파일은 프로젝트의 전반적인 사항들을 설정해주는 곳으로 , 루트 디렉토리를 포함한 각종 디레토리의 위치 , 로그의 형식, 프로젝트에 포함된 애플리케이션의 이름 등이 지정되어 있습니다.
1.ALLOWED_HOSTS 적절하게 지정해야 합니다.
DEBUG = True 개발모드로 , False이면 운영 모드로 인식합니다.
운영 모드인 경우는 ALLOWED_HOSTS에 반드시 서버의 Ip나 도메인을 지정해야 하고 , 개발 모드인 경우에는 값을 지정하지 않아도 locaolhost, 127.0.0.1로 간주
2.프로젝트에 포함되는 애플리케이션들은 모든 설정 파일에 등록되어야 합니다. 따라서 우리가 개발하고 있는 polls 애플리케이션도 등록해야 합니다. 애플리케이션을 등록할 때는 간단하게 애플리케이션의 모듈명인 ‘polls’만 등록해도 되자만, 애플리케이션의 설정 클래스로 등록하는 것이 더 정확한 방법입니다.
poll앱의 설정 클래스는 startapp polls 명령 시에 자동 생성된 apps.py파일에 PollsConfig라고 정의 되어 있습니다. 그래서 장고가 설정 클래스를 찾을 수 있도록 모듈 결올까지 포함하여 ‘polls.apps.PollsConfig’ 라고 등록합니다.
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK
c:\project\webprogram\ch3>dir
C 드라이브의 볼륨에는 이름이 없습니다.
볼륨 일련 번호: FCA3-2376
c:\project\webprogram\ch3 디렉터리
2020-06-18오후 04:46<DIR>.
2020-06-18오후 04:46<DIR>..
2020-06-18오후 04:46131,072 db.sqlite3
2020-06-18오후 04:11647 manage.py
2020-06-18오후 04:18<DIR>mysite
2020-06-18오후 04:46<DIR>polls
2개 파일131,719 바이트
4개 디렉터리134,454,546,432 바이트 남음
Migrate 명령은 데이터베이스에 변경사항이 있을 때 이를 반영해주는 명령입니다ㅣ.
이 명령이 필요한 이유 :
장고는 모든 웹 프로젝트 개발 시 반드시 사용자와 그룹 테이블 등이 필요하다는 가정하에 설계되었습니다. 그래서 우리가 테이블을 전혀 만들지 않았더라도 , 사용자 및 그룹 테이블 등을 만들어주기 위해서 프로젝트 개발 시작 시점에 이 명령을 실행하는 것입니다. 명령을 실행하면 migrate 명령에 대한 로그가 보이고 , 실행 결과로 sqlite3데이터베이스 파일인
django.유.models.Model클래스를 상속받아 정의하고 , 각 클래스 변수의 타입도 장고에서 미리 정의된 필드 클래스를 사용합니다.
Id는 자동생성해준다.
Pk ;클래스에 정의해주지 않아도 장고는 항상 PK에 대한 속성을 Not Null및 Autoincrement로 이름은 id로 해서 자동으로 만들어줍니다.
DateTimeFiled()필드 클래스에 정의한 date published 는 pub_Date컬럼에 대한 레이블 문구입니다. 나중에 설명하느 Admin사이트에서 이 문구를 보게 될 것입니다.
FK: 항상 다른 테이블의 pk에 연결된다.
__str__()메소드는 객체를 문자열로 표현할 때 사용하는 함수입니다. 나중에 보게 될 Admin사이트나 장고 쉘 등에서 테이블명을 보여줘야 하는뎅, 이때 __Str__()메소드를 정의하지 않으면 테이블명이 제대로 표시되지 않습니다. 파이썬 2에서는 __unicode__()메소드를 사용합니다.
Get_object_or_404()단축함수를 사용하고 있습니다. 이 함수의 첫번쨰 인자는 모델 클래스이고, 두번째 인자부터는 검색 조건을 여러 개 사용할 수 있습니다. 이 예제에서는 Question모델 클래스로 부터 pk = question_id검색 조건에 맞는 객체를 조회합니다. 조건에 맞는 객체가 없으면 Http404익셉션을 발생시킵니다.
Render()
Detail()
3.7.4 뷰 함수 vote() 및 리다이렉션 작성
Detail.html-> vote버튼 클릭 ->
c:\project\webprogram\ch3\polls >notepad views.py
from django.shortcuts import render
# Create your views here. from django.shortcuts importrender,get_object_or_404 from polls.models import Question from django.http import HttpResponseRedirect from polls.models import Choice,Question from django.urls import reverse