Django Template 및 View 구현하기

|

URL 과 View간 맵핑

Django에서 URLView는 1:1로 맵핑됨. 예를 들면 다음과 같은 형태로 맵핑할 수 있습니다.

URL 패턴 View 이름 처리하는 내용
/posts/ index() index.html 템플릿을 렌더링
/posts/3 detail() 각 포스트의 내용을 detail.html 템플릿을 통해 렌더링


urls.py 작성

urls.py에는 사이트로 요청된 URL을 이용해서 실행할 함수까지 맵핑을 할 수 있습니다. urls.py의 위치는 프로젝트 전체 영역에 해당하는 blog 디렉토리 아래에 위치하며, 각 어플리케이션마다 별도로 작성해서 관리할 수도 있습니다.

로직의 개발 순서는 정해지진 않았지만, URLConf -> View -> Template 형태로 개발하는 것이 일반적입니다.

여기서는 각 어플리케이션마다 urls.py 파일을 정의한 다음, 프로젝트 전체 URLConf에서 각 파일을 include 하도록 하는 예제가 포스팅되었습니다.


post/urls.py

urls.py 파일이 존재하지 않기 때문에 생성해줍니다. 맵핑될 URL 포맷은 정규식으로 작성합니다.

from django.contrib import admin
from django.urls import path

from django.conf.urls import url
from post import views

app_name = 'post'

urlpatterns = [
    url(r"^$", views.index, name="index"),
    # url(r"^(?P<post_id>\d+)/$", views.detail, name="detail"),
]


blog/urls.py

그리고, 프로젝트 전체에 해당하는 blog/urls.py에는 다음과 같이 작성합니다.

from django.contrib import admin
from django.urls import path

from django.conf.urls import url, include
from post import views

urlpatterns = [
    url(r"^admin/", admin.site.urls),
    url(r"^post/", include("post.urls", namespace="post")),
]


view 작성

from django.shortcuts import render
from post.models import Post


# Create your views here.

def index(request):
    post_list = Post.objects.all().order_by("-pub_date")[:10]
    context = {"post_list": post_list}
    return render(request, "post/index.html", context)


template 작성

post/templates/post/ 디렉토리 아래에 index.html 파일을 생성합니다.

{% if post_list %}
    <ul>
        {% for post in post_list %}
            <li><a href="/post/{{ post.id }}/">{{ post.title }}</a></li>
        {% endfor %}
    </ul>

{% else %}
    <p>Empty List</p>
{% endif %}


확인

그 이후 http://127.0.0.1:8000/admin 사이트에서 Post 테이블의 아이템을 추가한다음 http://127.0.0.1:8000/post에서 아이템 리스트를 조회할 수 있습니다.


추가 화면 구성

post/urls.py 수정

urlpatterns = [
    url(r"^$", views.index, name="index"),
    url(r"^(?P<post_id>\d+)/$", views.detail, name="detail"),
]


post/view.py 수정

from django.shortcuts import render, get_object_or_404
from post.models import Post


# Create your views here.

def index(request):
    post_list = Post.objects.all().order_by("-pub_date")[:10]
    context = {"post_list": post_list}
    return render(request, "post/index.html", context)


def detail(request, post_id):
    item = get_object_or_404(Post, pk=post_id)
    return render(request, "post/detail.html", {"post": item})


post/template/post/detail.html

<h1>{{ post.title }}</h1>
<h3>{{ post.text }}</h3>

Django 어플리케이션 생성 방법

|

Django 프로젝트 생성 이후 그 안에 어플리케이션을 생성하는 방법입니다. 다음은 post라는 어플리케이션을 생성한 다음 이루어지는 작업들입니다.

$ python3 manage.py startapp post


그 다음에는 어플리케이션에서 사용할 데이터 모델(Model)을 생성합니다.

Django는 기본적으로 SQLite3 데이터베이스를 사용하며, settings.py 파일에서 다른 데이터베이스를 사용할 수도 있습니다. settings.py에는 다음과 같이 데이터베이스가 설정되어 있습니다.

# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


post 어플리케이션을 settings.py에 등록하기

방금 생성한 post 어플리케이션을 setting.py 내에 다음과 같이 등록합니다.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'post',
]


타임존(TimeZone) 변경

settings.py내 타임존 부분을 변경합니다.

TIME_ZONE = 'Asia/Seoul'


데이터베이스 테이블(Table) 정의

위에서 생성한 post 어플리케이션내 models.py 파일에서 테이블을 정의할 수 있습니다.

from django.db import models


# Create your models here.

class Post(models.Model):
    pub_date = models.DateTimeField('date published')
    title = models.CharField(max_length=20)
    text = models.CharField(max_length=300)

    def __str__(self):
        return self.text


admin.py에 모델 반영

from django.contrib import admin
from post.models import Post

# Register your models here.
admin.site.register(Post)


그 이후 manage.py 파일의 makemigrations 명령어를 실행해서 데이터베이션에 변경사항을 반영(migration)합니다.

$ python3 manage.py makemigrations

Migrations for 'post':
  post/migrations/0001_initial.py
    - Create model Post



$ python3 manage.py migrate

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, post, sessions
Running migrations:
  Applying post.0001_initial... OK

그 이후 브라우저에서 http://127.0.0.1:8000/admin에 접속하면 방금 작업한 테이블이 잘 반영되어 있는 것을 확인할 수 있습니다.

Django 프로젝트 생성 방법

|

Django 프로젝트를 생성하는 방법입니다.


python 가상 환경 생성

가상 환경을 따로 구성하지 않아도 되지만, 여기서는 가상 환경 생성부터 포스팅합니다.

python3 -m venv snowdeer_env

위 명령어를 수행하면 snowdeer_env라는 virtualenv 가상 환경을 생성합니다. 현재 디렉토리내에 snowdeer_env라는 서브 디렉토리가 생성됩니다.


활성화

다음 명령어를 실행하면 조금 전에 생성한 가상 환경을 활성화(activate)합니다.

source snowdeer_env/bin/activate

(snowdeer_env) $


Django 설치

(snowdeer_env) $ sudo pip3 install Django


Django 프로젝트 생성

mkdir snowdeer_blog
cd snowdeer_blog

django-admin.py startproject blog

생성된 파일 구조는 다음과 같습니다.

$ tree snowdeer_blog

snowdeer_blog
└── blog
    ├── blog
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py


어플리케이션 생성

위에서 생성한 디렉토리 구조에서 manage.py 파일을 이용해서 나머지 작업을 수행할 수 있습니다.

$ python3 manage.py startapp post


Database 반영

Database는 migrate라는 명령어를 이용해서 생성 및 업데이트할 수 있습니다.

$ python3 manage.py migrate

Operations to perform:
  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 sessions.0001_initial... OK


실행 및 브라우저에서 확인

$ python3 manage.py runserver

Performing system checks...

System check identified no issues (0 silenced).
January 30, 2019 - 01:27:06
Django version 2.1.5, using settings 'blog.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

그 이후 브라우저에서 http://127.0.0.1:8000 또는 http://127.0.0.1:8000/admin으로 접속하면 확인할 수 있습니다.


admin 관리자 등록

$ python3 manage.py createsuperuser

그 이후 http://127.0.0.1:8000/admin에서 로그인 가능합니다.

Future에 Timeout 적용하기

|

Future에 Timeout 적용

future에 Timeout을 적용하는 예제입니다. ROS 2.0 관련 코드라 직접적으로 동작은 되지 않겠지만, wait_until()을 이용해서 특정 시간을 기다리는 점에서는 사용방법이 동일합니다.

thread t1([client]() {
    while (true) {
      auto a = 0;
      auto b = 0;

      cout << "Input two number: " << endl;
      cin >> a >> b;

      auto req = make_shared<Add::Request>();
      req->a = a;
      req->b = b;

      auto tp = std::chrono::system_clock::now() + std::chrono::seconds(3);
      auto request = client->async_send_request(req);
      auto status = request.wait_until(tp);

      if (status == future_status::ready) {
        auto resp = request.get();
        cout << "Sum : " << resp->sum << endl;
      } else {
        cout << "Timeout !!!" << endl;
      }
    }
  });

ROS 2.0 Crystal 설치 방법

|

ROS 2.0 Crystal 버전이 새로 나왔습니다. 역시나 기존의 ArdentBouncy 버전 때와 설치 방법이 조금 다른데, 그래도 거의 Bouncy 때의 설치 과정과 유사합니다.

아래 포스팅은 Ubuntu 18.04 버전을 처음 설치했다고 가정하고(아무런 패키지가 설치되지 않은 상태), ROS 2.0 Crystal 버전을 설치하는 과정입니다.


Locale 설정

sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8


기본 패키지 설치 및 repo key 설치

sudo apt update && sudo apt install curl gnupg2 lsb-release
curl http://repo.ros2.org/repos.key | sudo apt-key add -


vcs-tool 설치

sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 0xB01FA116
sudo apt-get update
sudo apt-get install python3-vcstool


기본 컴포넌트들 설치

sudo apt update && sudo apt install -y \
  build-essential \
  cmake \
  git \
  python3-colcon-common-extensions \
  python3-pip \
  wget

sudo apt install -y libpython3-dev

python3 -m pip install -U \
  argcomplete \
  flake8 \
  flake8-blind-except \
  flake8-builtins \
  flake8-class-newline \
  flake8-comprehensions \

  flake8-deprecated \
  flake8-docstrings \
  flake8-import-order \
  flake8-quotes \
  git+https://github.com/lark-parser/lark.git@0.7d \
  pytest-repeat \
  pytest-rerunfailures \
  pytest \
  pytest-cov \
  pytest-runner \
  setuptools

sudo apt install --no-install-recommends -y \
  libasio-dev \
  libtinyxml2-dev


ROS 2.0 바이너리 다운로드 및 설치

미리 빌드된 ROS 2.0 바이너리를 다운로드합니다. 그리고 아래 명령어로 압축해제를 합니다.

mkdir -p ~/ros2_install
cd ~/ros2_install
tar xf ~/Downloads/ros2-crystal-20190117-linux-bionic-amd64.tar.bz2


rosdep 설치 및 초기화

sudo apt install -y python-rosdep

sudo rosdep init
sudo rosdep fix-permissions
rosdep update

만약 중간에 catkin-pkg 버전 때문에 에러가 발생하면 아래 명령어를 이용해서 버전 업데이트를 해줍니다.

sudo apt-get update && sudo apt-get install --only-upgrade python-catkin-pkg


OpenSlice 및 RTI Connext

OpenSliceRTI Connext는 굳이 설치를 할 필요는 없습니다. (어차피 상용 License라 사용하기엔 애매합니다.)

여기서는 패스합니다.


설치 확인

창을 2개 열어서 다음 명령어가 잘 동작하는지 확인합니다.~~~~

. ~/ros2_install/ros2-linux/setup.bash
ros2 run demo_nodes_cpp talker


. ~/ros2_install/ros2-linux/setup.bash
ros2 run demo_nodes_cpp listener