docker network

Docker 컨테이너(container)는 격리된 환경에서 돌아가기 때문에 기본적으로 다른 컨테이너와의 통신이 불가능합니다. 하지만 여러 개의 컨테이너를 하나의 Docker 네트워크(network)에 연결시키면 서로 통신이 가능해집니다.

portainer 에서 network 생성

network -> add network

name -> nginx-django 생성

container 를 network에 연결

container -> add container 의 하단부

container name 지정할때 주의 -> container name == host name

network 탭에서 container가 참가할 네트워크를 찾아 설정

network 내에서 요청

docker network 내에서는 컨테이너 이름을 호스트 네임으로 사용

그렇기에 nignx.conf 같은 설정에서 django 같은 서버를 호출할때 

컨테이너네임:포트번호 를 주소로 사용

아래의 proxy_pass 부분

worker_processes auto;

events {
}

http {
  server {
    listen 80;

    location / {
        proxy_pass http://django_container_gunicorn:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
  }
}

 

728x90

네트워크 생성 이유

컨테이너 이름을 기반으로 서로 요청을 주고 받기 위해 생성

네트워크 생성

network -> add network

name 직관적으로 설정

컨테이너 생성

1. django container

name, image 지정

network 탭에서 위에서 만든 네트워크 지정

2. nginx 컨테이너 생성

name, image 지정

nginx는 사용자와의 통신을 위해 외부 포트 연결 필요 

참가할 네트워크 지정

nginx 설정파일 연결 (컨테이너 외부 파일을 내부로 연결시킬때 volumes의 bind를 통해 지정)

728x90

'Study > Docker' 카테고리의 다른 글

[Docker] portainer를 이용한 docker network 구성  (0) 2021.05.28
[Docker] aws ec2 Linux2, docker, portainer  (0) 2021.05.26

aws ec2 linux2 , docker, portainer

aws ec2 인스턴스에 docker 설치

  1. 인스턴스에 설치한 패키지 및 패키지 캐시를 업데이트합니다.
sudo yum update -y
  1. 최신 도커 엔진 패키지를 설치합니다.
  • Amazon Linux 2
sudo amazon-linux-extras install docker
  1. 도커 서비스를 시작합니다.
sudo service docker start
  1. ec2-user를 사용하지 않고도 도커 명령을 실행할 수 있도록 docker 그룹에 sudo.를 추가합니다.
sudo usermod -a -G docker ec2-user
  1. 로그아웃하고 다시 로그인해서 새 docker 그룹 권한을 선택합니다. 이를 위해 현재 SSH 터미널 창을 닫고 새 창에서 인스턴스를 다시 연결할 수 있습니다. 새 SSH 세션은 해당되는 docker 그룹 권한을 갖게 됩니다.

  2. ec2-user 없이도 sudo.가 도커 명령을 실행할 수 있는지 확인합니다.

docker info

portainer 설치

공식 사이트
https://documentation.portainer.io/v2.0/deploy/ceinstalldocker/

  1. portainer를 설치할 volume 생성
docker volume create portainer\_data
  1. portainer 다운 및 9000 포트에서 실행
docker run -d -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer\_data:/data portainer/portainer-ce

portainer 접속

주소창에 호스트 : 9000

docker swarm

docker swarm init

아래 내용이 나오면 성공

728x90

field lookup

공식문서

https://docs.djangoproject.com/en/3.0/ref/models/querysets/#id4

  • SQL의 WHERE에 해당되는 기능

  • QuerySet메소드인 filter(), exclude(), get()등에 키워드 인자로 지정

  • 어떤 lookup type에도 해당이 안 될 경우(Example.objects.get(id=1)) 자동적으로 exact로 적용

  • 사용법은 fieldname__lookuptype (Example.objects.get(id__exact=1)


exact

정확하게 일치하는 값을 검색.

None값을 넣게 되면 SQL의 IS NULL 구문을 사용하는 것과 같다.

# WHERE id = 14;
Entry.objects.get(id__exact=14) 
# WHERE id IS NULL;
Entry.objects.get(id__exact=None) 

iexact

대소문자의 구분없이 정확하게 일치하는 값을 검색.

None값을 넣게 되면 SQL의 IS NULL구문을 사용 하는 것과 같다.

# WHERE name ILIKE 'beatles blog';
Blog.objects.get(name__iexact='beatles blog')
# WHERE name IS NULL;
Blog.objects.get(name__iexact=None)

contains

대소문자를 구분하고 문자열을 포함하고 있는 것을 검색.

# WHERE headline LIKE '%Lennon%';
Entry.objects.get(headline__contains='Lennon')

icontains

대소문자를 구분하지 않고 문자열을 포함하고 있는 것을 검색.

# WHERE headline ILIKE '%Lennon%';
Entry.objects.get(headline__icontains='Lennon')

in

  • 주어진 iterable한 객체(리스트, 튜플, 쿼리셋)에 포함되어 있는지 검색.

    # WHERE id IN (1,3,4);
    Entry.objects.filter(id__in=[1,3,4])
  • 쿼리셋을 사용하여 동적으로도 검색이 가능하다.

    # WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE='%Cheddar%')
    inner_qs = Blog.objects.filter(name__contains='%Cheddar%')
    entries = Entry.objects.filter(blog__in=inner_qs)
  • values() 나 values_list()를 쓸 __in에 쓸 경우 결과 값은 하나의 필드만을 반환 해야 한다.

    inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
    entries = Entry.objects.filter(blog__name__in=inner_qs)
  • 만약 두개의 필드로 반환하는 values()를 할 경우 TypeError를 raise를 시킬 것이다.

    # Bad code! Will raise a TypeError.
    inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
    entries = Entry.objects.filter(blog__name__in=inner_qs)
  • 중첩된 쿼리를 사용 할 때는 데이터베이스의 성능 특성을 이해하고 써야 한다. 일부 데이터베이스의 경우 중첩 쿼리를 잘 처리 하지 못한다. 그래서 __in에 대한 list 목록을 미리 추출하여 두번째 쿼리에 해당 list를 사용 하는것이 더 좋다.

    values = Blog.objects.filter(name__contains='Cheddar').values_list('pk', flat=True)
    entries = Entry.objects.filter(blog__in=list(values))

    두번째 쿼리에서 list()를 사용하여 첫번째 쿼리를 강제로 실행. 중첩 쿼리를 실행하지 않게 한다. - in을 실행하면서 Entry를 계속 검색하는데 거기서 values 쿼리가 중복하여 실행된다. 그것을 방지.

gt, gte

  • gt : ~보다 큰.
  • gte : ~보다 크거나 같은.
    # WHERE id > 4;
    Entry.objects.filter(id__gt=4)
    # WHERE id >= 4;
    Entry.objects.filter(id__gte=4)

lt, lte

  • lt : ~보다 작은.
  • lte : ~보다 작거나 같은.
    # WHERE id < 4;
    Entry.objects.filter(id__lt=4)
    # WHERE id <= 4;
    Entry.objects.filter(id__lte=4)

startswith, istartswith

  • startswith : 대소문자를 구분하여 시작하는 문자열.
  • istartswith: 대소문자를 구분하지 않고 시작하는 문자열.
    # WHERE headline LIKE 'Lennon%';
    Entry.objects.filter(headline__startswith='Lennon')
    # WHERE headline ILIKE 'Lennon%';
    Entry.objects.filter(headline__istartswith='Lennon')

endswith, iendswith

  • endswith : 대소문자를 구분하여 끝나는 문자열.
  • iendswith: 대소문자를 구분하지 않고 끝나는 문자열.
    # WHERE headline LIKE '%Lennon';
    Entry.objects.filter(headline__endswith='Lennon')
    # WHERE headline ILIKE '%Lennon';
    Entry.objects.filter(headline__iendswith='Lennon')

range

  • 범위를 안에 있는지 검색.
    start_date = date(2005, 1, 1)
    end_date = date(2005, 3, 31)
    # WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
    Entry.objects.filter(pub_date__range(start_date, end_date))
  • SQL에서 BETWEEN을 날짜, 숫자, 문자에서 사용하는 것처럼 range도 사용 가능하다.
    날짜가 있는 DateTimeField를 필터링 하는 경우 마지막 날의 항목은 포함하지 않는다. 왜냐하면 주어진 날짜의 오전 0시로 경계가 설정되기 때문.
    WHERE pub_date BETWEEN '2005-01-01 00:00::00' and '2005-03-31 00:00:00';
  • 일반적으로 dates와 datetimes를 섞어쓰면 안된다.

date

  • datetime 필드의 경우 값을 날짜로 변환한다. 추가 체인이 가능하고, date값을 사용 한다.
    Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
    Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

year

  • date 및 datetime의 필드에서 년도가 정확히 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하고 정수를 나타낸다.
    # WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
    Entry.objects.filter(pub_date__year=2005)
    # WHERE pub_date >= '2005-01-01';
    Entry.objects.filter(pub_date__year__gte=2005)

month

  • date 및 datetime의 필드에서 달이 정확히 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하고 정수1 부터 12까지 나타낸다.
    # WHERE EXTRACT('month' FROM pub_date) = '12';
    Entry.objects.filter(pub_date__month=12)
    # WHERE EXTRACT('month' FROM pub_date) >= '6';
    Entry.objects.filter(pub_date__month__gte=6)

day

  • date 및 datetime의 필드에서 일이 정확히 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하고, 정수를 나타낸다.
    # WHERE EXTRACT('day' FORM pub_date) = '3';
    Entry.objects.filter(pub_date__day=3)
    # WHERE EXTRACT('day' FORM pub_date) >= '3';
    Entry.objects.filter(pub_date__day__gte=3)

week

  • date 및 datetime의 필드에서 ISO-8601의 기준에 따라 주 번호(1-52 또는 53)을 반환한다. 즉 월요일에 시작하는 주 및 첫번째 주는 목요일에 시작한다.
    Entry.objects.filter(pub_date__week=52)
    Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)

week_day

  • date 및 datetime 필드에서 요일과 정확하게 일치 하는 것을 검색한다. 추가 체인 필드 검색이 가능하다. 정수1 부터 7까지 나타낸다.
    Entry.objects.filter(pub_date__week_day=2)
    Entry.objects.filter(pub_date__week_day__gte=2)
    연도와 월에 상관없이 1(일요일)과 7(토요일)사이에서 색인된다.

quarter

  • date 및 datetime 필드에서 분기가 정확하게 일치 하는 것을 검색한다. 추가 체인 필드 검색이 가능하며, 1년의 1/4인 1에서 4까지 나타낸다.
    # 2분기 검색
    Entry.objects.filter(pub_date__quarter=2)

time

  • datetime필드의 경우 값을 시간으로 변경하여 검색. 추가 체인 필드 검색이 가능하고, datetime.time값을 사용한다.
    Entry.objects.filter(pub_date__time=datetime.time(14, 30))
    Entry.objects.filter(pub_date__time__between=(datetime.time(8), datetime.time(17)))

hour

  • datetime 및 time 필드에서 시간이 정확하게 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하며, 0에서 23사이를 나타낸다.
    # WHERE EXTRACT('hour' FROM timestamp) = '23';
    Event.objects.filter(timestamp__hour23)
    # WHERE EXTRACT('hour' FROM time) = '5';
    Event.objects.filter(time_hour=5)
    # WHERE EXTRACT('hour' FROM timestamp) >= '12';
    Event.objects.filter(timestamp__hour__gte=12)

minute

  • datetime 및 time 필드에서 분이 정확하게 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하며, 0에서 59사이를 나타낸다.
    # WHERE EXTRACT('minute' FROM timestamp) = '29';
    Event.objects.filter(timestamp__minute=29)
    # WHERE EXTRACT('minute' FROM time) = '46';
    Event.objects.filter(time__minute=46)
    # WHERE EXTRACT('minute' FROM timestamp) >= '29';
    Event.objects.filter(timestamp__minute__gte=29)

second

  • datetime 및 time 필드에서 초가 정확하게 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하며, 0에서 59사이를 나타낸다.
    # WHERE EXTRACT('second' FROM timestamp) = '31';
    Event.objects.filter(timestamp__second=31)
    # WHERE EXTRACT('second' FROM time) = '2';
    Event.objects.filter(time__second=2)
    # WHERE EXTRACT('second' FROM timestamp) >= '31';
    Event.objects.filter(timestamp__second__gte=31)

isnull

  • IS NULL 과 IS NOT NULL에 대한 True, False값을 검색한다.
    # WHERE pub_date IS NULL;
    Entry.objects.filter(pub_date__isnull=True)

regex, iregex

  • regex : 대소문자를 구분하여 정규식을 검색.
  • iregex : 대소문자를 구분하지 않고 정규식을 검색.
    # WHERE title REGEXP '^(An?|The) +';
    Entry.objects.get(title__regex=r'^(An|The) +')
    # WHERE title REGEXP '(?i)^(an?|the) +'l;
    Entry.objects.get(title__iregex=r'^(an?|the) +'
    정규식을 전달하기 위해 r을 붙이는게 좋다.
728x90

'Study > Django' 카테고리의 다른 글

[Django] gunicorn  (0) 2021.05.28
[Django] 배포를 위한 환경파일 분리  (0) 2021.05.28
[Django] decorator  (0) 2021.05.25
[Django] code formatting black 설치 및 적용  (0) 2021.05.20
[Django] 환경 변수 분리하기 django-environ  (0) 2021.05.18

상세페이지의 update,delete를 위한 소유권 확인

  1. 상세페이지의 pk 가져오기

urls.py

urlpatterns = [
    path(
        "update/<int:pk>",
        ArticleUpdateView.as_view(),
        name="update",
    ),
    path(
        "delete/<int:pk>",
        ArticleDeleteView.as_view(),
        name="delete",
    ),
]
  1. decorator 생성시 글 작성자와 로그인한 유저가 동일한지 확인

decorators.py

from django.http import HttpResponseForbidden

from articleapp.models import Article


def article_ownership_required(func):
    def decorated(request, *args, **kwargs):
        article = Article.objects.get(pk=kwargs["pk"])
        if not article.writer == request.user:
            return HttpResponseForbidden()
        return func(request, *args, **kwargs)

    return decorated
  1. view에서 실제로 적용하기

views.py

@method_decorator(article_ownership_required, "get")
@method_decorator(article_ownership_required, "post")
class ArticleUpdateView(UpdateView):
    model = Article
    form_class = ArticleCreationForm
    context_object_name = "target_article"
    template_name = "articleapp/update.html"

    def get_success_url(self):
        return reverse("articleapp:detail", kwargs={"pk": self.object.pk})
  1. 리스트형태로 decorator 가져오기 가능

views.py


# decorators.py에서 사용할 decorator를 가져와 리스트에 삽입
has_owership = [login_required, article_ownership_required]

@method_decorator(has_owership, "get")
@method_decorator(has_owership, "post")
class ArticleUpdateView(UpdateView):
    model = Article
    form_class = ArticleCreationForm
    context_object_name = "target_article"
    template_name = "articleapp/update.html"

    def get_success_url(self):
        return reverse("articleapp:detail", kwargs={"pk": self.object.pk})
728x90

decorator

decorator ?

함수를 받아 명령을 추가한 뒤 이를 다시 함수의 형태로 반환하는 함수이다.
함수의 내부를 수정하지 않고 기능에 변화를 주고 싶을 때 사용한다 .
일반적으로 함수의 전처리나 후처리에 대한 필요가 있을때 사용을 한다.
또한 데코레이터를 이용해, 반복을 줄이고 메소드나 함수의 책임을 확장한다

decorator는 원래 작업의 앞 뒤에 추가적인 작업을 손쉽게 사용 가능하도록 도와주는 역할

데코레이터의 구조

함수형

def out_func(func):  # 기능을 추가할 함수를 인자로

    def inner_func(*args, **kwargs):

        return func(*args, **kwargs)

    return inner_func

example

# decorator 정의
def decorator(func):
    def wrapper(*args, **kwargs):

        print('전처리')   
        print(func(*args, **kwargs))
        print('후처리')
    return wrapper

# decorator 사용
@decorator
def example():
    return '함수'

#############
example()
'''''''''
전처리
함수
후처리
'''''''''

클래스형

class Decorator:

    def __init__(self, function):
        self.function = function

    def __call__(self, *args, **kwargs):
        return self.function(*args, **kwargs)

example

class Decorator:

    def __init__(self, function):
        self.function = function

    def __call__(self, *args, **kwargs):
        print('전처리')
        print(self.function(*args, **kwargs))
        print('후처리')

@Decorator
def example():
    return '클래스'

example()
'''''''''
전처리
클래스
후처리
'''''''''

django decorator

FBV

from django.contrib.auth.decorators import login_required
from django.shortcuts import render

# 방법 1
@login_required
def post_create(request):
  # 생략
  return render(request, 'core/index.html')


# 방법 2
def post_create(request):
  # 생략
  return render(request, 'core/index.html')

post_create = login_required(post_create)

CBV

방법 3 추천

# 방법 1

from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView

class MyTemplateView(TemplateView):
    template_name= "core/index.html"

index = MyTemplateView.as_view()
index = login_required(index)

# 방법 2

from django.utils.decorators import method_decorator

class MyTemplateView(TemplateView):
    template_name= "core/index.html"

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
      return super().dispatch(*args, **kwargs)

index = MyTemplateView.as_view()

# 방법 3

@method_decorator(login_required, name="dispatch")
class MyTemplateView(TemplateView):
    template_name= "core/index.html"


index = MyTemplateView.as_view()
728x90

+ Recent posts