Django

DevInCafe

Installing Python and Pip on OS X

Install homebrew

 

Install Python

 

brew install python

brew install python3

Virtualenv

demo/bin dir 안에,

그 env만의 python, pip, 다른 excutables 이 있다.

which python3

virtualenv -p /usr/local/bin/python3 demo
. bin/activate

virtualenv 실행

Virtualenv

pip으로 설치한 패키지들이 모이는 곳

다른 env와 분리된다.

lib/python3/site-packages

새 프로젝트 만들기

django-admin.py startproject projectname

cd projectname

python manage.py migrate

python manage.py runserver

Apps

python manage.py startapp appname

한개의 프로젝트는 여러개의 앱으로 구성

(로그인, 게시판, 구매...)

app 생성 다음 settings.py에 등록

URL Mappings

url(r'^$', 'main.views.home')

In urls.py

raw string for 정규표현식

Django views

MVC 의 C ('controller')

Templates

In views.py function

def home(request):

...
...

   return render(request, "main/home.html")

Templates

In views.py function

def home(request):

...
...

   return render(request, "main/home.html")

static file들이 template 안에 있다면

request할때마다 static file이 reload 된다.

-> 따로 관리하자

Static files

In settings.py

STATICFILES_DIR = (os.path.join(BASE_DIR, "static", )

내 template 안에서 호출하기

{% load staticfiles %}

<link href="{% static 'bootstrap/js/ ....' %}">

Static files

In settings.py

 

STATIC_URL

static file URL의 맨 처음 부분 지정

template html

개발자 도구로 확인 가능

 

STATICFILES_DIRS

(장고가) static file들을 어디서 찾을 수 있는지

 Models

from django.contrib.auth.models import User

class Game(models.Model):

    first_player = models.ForeignKey(User)

 Model migrate

python manage.py createsuperuser

python manage.py makemigrations

python manage.py migrate

Admin Interface

class Game(models.Model):
    ...
    ...
    def __str__(self):
        return "{0} vs {1}".
              format(self.first_player, self.second_player)

In admin.py 내 model 등록

 

In models.py

admin 페이지에서 인스턴스의 제목 표시

Model API

python manage.py shell
from app.models import Game, Move

Game.objects.all()
Game.objects.get(pk=1)
Game.objects.filter(status = "A")
Game.objects.exclude(status = "A")
Game.objects.filter(first_player__username = "mj")

ORM - 파이썬 코드로 db data 조작

Model API(cont)

m = Move(x = 1, y = 2)
m.save()

g = Game.objects.get(pk=1)
g.move_set
g.move_set.count()
g.move_set.exclude(comment= '')

g.status = 'D'
g.save()

ORM - 파이썬 코드로 db data 조작

Adding Login and Logout views

urlpatterns += patterns( 'django.contrib.auth.views',
    url(r'^login/$', 'login', 
        {'template_name' : 'login.html'},
        name = 'boardgames_login')

In urls.py

In settings.py

LOGIN_URL = 'boardgames_login'
LOGIN_REDIRECT_URL = 'home'
LOGOUT_URL = 'boardgames_logout'

Django가 지원하는 login 관련 기능

Adding Login and Logout views

<li>
    <a href="{% url 'boardgames_login' %}">로그인</a>
</li>

In login.html

URL Mappings for Apps

url(r'^prefix/', include('myapp.urls'))

각 App마다 별도로 url 관리하기

In project's urls.py

Template Inheritance

{% extends "base.html" %}
{% block content %}
    ...
    ...
{% endblock content %}

overwritten by children

Template Inheritance

{% extends "base.html" %}
{% block content %}
    {{ block.super }}
    ...
    ...
{% endblock content %}

Login Required

from django.contrib.auth.decorators import login_required

@login_required
def home(request):
    ...
    return render(request, "... ")

In views.py

View 에서 Template로 data 전달하기

{% include "snippet.html" with header = "data1" games_list = waiting_games %}
{% include "snippet.html" with header = "data2" games_list = active_games %}
{% include "snippet.html" with header = "data3" games_list = other_games%}

1. In views.py function, 

db data를 tamplate으로 전달 (render)

db data => dictionary

2. template 가 data별로 처리

View 에서 Template로 data 전달하기

{% for game in games_list %}
    ...
    ...
{% empty %}
    ...
{% endfor %}

3. In snippet.html , for tag 사용

Custom Manager Class

class GamesManager(models.Manager):
    def games_for_user(self, user):

class Game(models.Model):
    objects = GamesManager()

In models.py

models.Manager를 상속하는 클래스 생성

Manager는 모든 table을 보여줌

table 레벨에서 무언가 하고 싶을 때

Custom Manager Class

def home(request):
    my_games = Game.objects.games_for_user(request.user)

In views.py

Adding a HTML Form

class Invitation(models.Model):
    from_user = models.ForeignKey(User, related_name = "user_inviting")
    to_user   = models.ForeignKey(User, related_name = "user_invited")

In models.py

User.Invition_set   <-  crash

Adding a HTML Form

def new_invitation(request):
    if request.method == "POST":
        form = InvitationForm(data = request.POST)
        if form.is_valid():
            form.save()
            return redirect('user_home')
   
        else:
            form = InvitationForm()
    return render(request, "test.html", {'form' : form})

Django가 Model class에 맞춰 input field 생성

app에 forms.py 파일 새로 만들기

In views.py,

Adding a HTML Form

<form action="" method="POST">
    {% csrf_token %}
    {{ form }}
    <button type="submit"> 전송 </button>
</form>

In template,

Named Groups

url(r'^invitation/(?P<pk>\d+)/$', 'accept_invitation', name="accept_invitation")

In urls.py

def accept_invitation(request, pk):
    invitation = get_object_or_404(Invitation, pk=pk)

In views.py

Reverse and get_absolute_url

def get_absolute_url(self):
    return reverse('detail', args=[self.id])

In models.py

function detail_page(request):
    ...
    ... 
    return redirect(game)

In views.py

Generic Views

Class views, not function

view 에서 패턴화된 것들을 자동화

코드를 더 짧게

url(r'^signup$', SignUpView.as_view(), name="sign_up_page")

CreateView / ListView / DetailView / TemplateView / UpdateView / DeleteView

In urls.py

Made with Slides.com