django-admin startproject '프로젝트명'
python manage.py runserver
django developement server가 시작되면 메세지가 출력되며 메세지 중간에 웹 서비스의 url주소를( http://127.0.0.1:8000 ) 찾을 수 있다.
python manage.py startapp 'app이름' #을 실행한다
- MTV 패턴
django는 model template view라는 MTV패턴을 따르고 있다.
MTV는 MVC(model view controller)와 유사한데 장고는 컨트롤러 역활을 장고 프레임워크 자체에서 한다고 본다.
뷰로부터 전달된 데이터를 템플릿에 적용하여 다이나믹한 웹페이지를 만든다.
- app template 폴더 만들 때 주의사항
app폴더 밑에 템플릿 서브 폴더를 만들고 다시 그 안에 app명을 사용하여 서브폴더를 만든 후 템플릿 파일을 그 안에 넣기를 권장한다.
만약 복수의 앱들이 동일한 템플릿을 가진 경우 뷰에서 잘못된 템플릿을 가져올 수 있다.
템플릿을 찾을 때 자신의 앱 내의 템플릿을 먼저 찾는것이 아니라 전체 앱들의 템플릿 폴더들을 처음부터 순서대로 찾기 때문이다.
템플릿을 html로만 쓰여진 static html 파일일 수 있지만 거의 대부분의 경우 뷰로부터 어떤 데이터를 전달받아 html템플릿 안에 그 데이터를 동적으로 치환해서 사용한다.
ex) index 뷰에서 message 라는 데이타를 index.html 이라는 템블릿에 전달하고 그 템플릿 안에서 이를 사용하기 위해서 다음과 같이 할 수 있다.
(1) 먼저 View (home/views.py)에서 다음과 같이 index()를 정의한다. 여기서 render는 django.shortcuts 패키지에 있는 함수로서 첫번째 파라미터로 request를, 그리고 두번째 파라미터로 템플릿을 받아들인다.
여기서 템플릿은 index.html으로 지정되어 있는데, 이는 home/templates/index.html을 가리키게 된다. 세번째 파라미터는 Optional 인데, View에서 템플릿에 전달한 데이타를 Dictionary로 전달한다.
Dictionary의 Key는 템플릿에서 사용할 키(or 변수명)이고, Value는 전달하는 데이타의 내용을 담는다. 여기서는 message 라는 키로 "My Message"라는 문자열을 전달하고 있다.
def index(request):
msg = 'My Message'
return render(request, 'home/index.html', {'message': msg}
(2) 다음으로 Template (home/templates/index.html)에 HTML 문서를 작성한다. 여기서 body 태그 안에 message를 보면 {{ }} 으로 둘러싸인 것을 볼 수 있는데, Django의 템플릿에서 {{ 변수명 }} 은 해당 변수의 값을 그 자리에 치환하라는 의미를 갖는다. Django Template은 또한 View로 부터 전달된 다양한 데이타들을 템플릿에 편리하게 넣을 수 있도록 여러 템플릿 태크( {% 탬플릿태그 %} 와 같은 형태)들을 제공하고 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{message}}</h1>
</body>
</htmㅣ>
{{변수}}
템플릿 필터는 변수의 값을 특정한 포맷으로 변형하는 기능을 한다. 예를 들어, 날짜를 특정 날짜 포맷으로 변경하거나 문자열을 대소문자로 변경하는 일등을 할 수 있다.
{{ createDate|date:"Y-m-d" }}
{{ lastName|lower }}
{# 1 라인 코멘트 #}
{% comment %}
<div>
<p>
불필요한 블럭
</p>
<span></span>
</div>
{% endcomment %}
HTML 내용 중에 <, >, ', ", & 등과 같은 문자들이 있을 경우 이를 그 문자에 상응하는 HTML Entity로 변환해 주어야 하는데, Django 템플릿에서 이러한 작업을 자동으로 처리해 주기 위해 {% autoescape on %} 템플릿 태그나 escape 라는 필터를 사용한다.
예를 들어, 아래 예제에서 content 라는 변수에 인용부호가 들어 있다고 했을 때, 아래와 같이 autoescape 태그나 escape 필터를 사용해서 자동으로 변환하게 할 수 있다. 만약 이러한 변환을 하지 않으면 HTML이 중간에 깨지게 된다.
{% autoescape on %} # autoescape 태그
{{ content }}
{% endautoescape %}
{{ content|escape }} # escape 필터
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
1) On Delete
Cascade : 부모 데이터 삭제 시 자식 데이터도 삭제
Set null : 부모 데이터 삭제 시 자식 테이블의 참조 컬럼을 Null로 업데이트
Set default : 부모 데이터 삭제 시 자식 테이블의 참조 컬럼을 Default 값으로 업데이트
Restrict : 자식 테이블이 참조하고 있을 경우, 데이터 삭제 불가
No Action : Restrict와 동일, 옵션을 지정하지 않았을 경우 자동으로 선택된다.
2) On Update
Cascade : 부모 데이터 업데이트 시 자식 데이터도 업데이트
Set null : 부모 데이터 업데이트 시 자식 테이블의 참조 컬럼을 Null로 업데이트
Set default : 부모 데이터 업데이트 시 자식 테이블의 참조 컬럼을 Default 값으로 업데이트
Restrict : 자식 테이블이 참조하고 있을 경우, 업데이트 불가
No Action : Restrict와 동일, 옵션을 지정하지 않았을 경우 자동으로 선택된다.
foriegnkey 출처
https://bamdule.tistory.com/45
1.settings.py 파일 안의 INSTALLED_APPS 리스트에 (만약 이미 추가되지 않았다면) 해당 Django App을 추가한다.
$ ./manage.py makemigrations
$ ./manage.py migrate
$ ./manage.py dbshell
class MainView(View):
def post(self, request):
data = json.loads(request.body)
Users(
name = data['name'],
email = data['email'],
password = data['password']
).save()
return JsonResponse({'message':'SUCCESS'}, status=200)
- all() : 테이블 데이타를 전부 가져오기 위해서는 Feedback.objects.all() 과 같이 all() 메서드를 사용한다. 다음은 Feedback 테이블의 모든 데이타의 id와 name 컬럼을 출력하는 예이다.
for f in Feedback.objects.all(): s += str(f.id) + ' : ' + f.name + '\n'
get()과 같이 단일 행의 결과가 존재하지 않을 경우 모델명.DoesNotExist의 exception으로 처리되지만 all()과 같은 여러 행이 나오는 경우엔 exception이 아닌 빈 값으로 처리된다.
- get() : 하나의 Row만을 가져오기 위해서는 get() 메서드를 사용한다. 예를 들어, 아래는 Primary Key (일반적으로 id 컬럼)가 1인 row를 가져온다.
타입이 Query Set이 아닌 단일행으로 나온다.row = Feedback.objects.get(pk=1) print(row.name)
filter() : 특정 조건에 맞는 Row들을 가져오기 위해서는 filter() 메서드를 사용한다. 예를 들어, 아래는 name 필드가 Kim 인 데이타만 가져온다.
rows = Feedback.objects.filter(name='Kim')
- exclude() : 특정 조건을 제외한 나머지 Row들을 가져오기 위해서는 exclude() 메서드를 사용한다. 예를 들어, 아래는 name 필드가 Kim이 아닌 데이타만 가져온다.
rows = Feedback.objects.exclude(name='Kim')
- count() : 데이타의 갯수(row 수)를 세기 위해 count() 메서드를 사용한다.
n = Feedback.objects.count()
- order_by() : 데이타를 키에 따라 정렬하기 위해 order_by() 메서드를 사용한다. order_by() 안에는 정렬 키를 나열할 수 있는데, 앞에 -가 붙으면 내림차순이다. 아래는 id를 기준으로 올림차순, createDate로 내림차순으로 정렬하게 된다.
rows = Feedback.objects.order_by('id', '-createData')
- distinct() : 중복된 값은 하나로만 표시하기 위해 distinct() 메서드를 사용한다. 아래는 name필드가 중복되는 경우 한번만 표시하게 된다.
rows = Feedback.objects.distinct('name')
- first() : 데이타들 중 처음에 있는 row만을 리턴한다. 아래는 name필드로 정렬했을 때 처음 row를 리턴한다.
rows = Feedback.objects.order_by('name').first()
- last() : 데이타들 중 마지막에 있는 row만을 리턴한다. 아래는 name필드로 정렬했을 때 마지막 row를 리턴한다.
rows = Feedback.objects.order_by('name').last()
- 쿼리 메서드들은 하나 하나가 실제 데이타 결과를 직접 리턴한다기 보다는 쿼리 표현식(Django에서 QuerySet이라 한다)을 리턴하는데, 여러 메서드들을 체인처럼 연결하여 사용할 수 있다.
- 여러 체인으로 연결되어 리턴된 쿼리가 해석되어 DB에 실제 하나의 쿼리를 보내게 된다. 아래는 여러 메서드들을 사용하여 체인으로 연결한 예제이다.
row = Feedback.objects.filter(name='Kim').order_by('-id').first()
fb = Feedback.objects.get(pk=1)
fb.name = 'Park'
fb.save()
fb = Feedback.objects.get(pk=2)
fb.delete()
from django.urls import path
from home import views
urlpatterns = [
path('', views.index),
path('ads.txt', views.ads),
]
# myweb/urls.py
from django.urls import path
import feedback.views
urlpatterns = [
path('feedback/<int:id>/', feedback.views.display)
]
</int:id>
# feedback/views.py
def display(request, id):
s = "ID = " + str(id)
return HttpResponse(s)
- Django에 내장된 Path Converter
from django.db import models
class Feedback(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
comment = models.TextField(null=True)
createDate = models.DateTimeField(auto_now_add=True)
내용 출처
http://pythonstudy.xyz/python/article/308-Django-모델-Model