Разные проекты на Python Django./ Карточная игра на Django + Typescript.

Теги: card js python

Карточная игра на Django + Typescript.

Django. Начало работы.

Создаем папку проекта.

mkdir news
cd news

Создаем и активируем виртуальное окружение для python 2.

virtualenv -p python3 venv
. ./venv/bin/activate

Или так для python 3

python3 -m venv venv

Создаем файл с зависимостями requirements.txt.

Django

Ставим django.

python -m pip install -r requirements.txt

Создаем проект.

django-admin startproject news

Меняем директорию и создаем базу данных.

cd news
./manage.py migrate

Стартуем веб-сервер разработки.

./manage.py startserver

start page

Заходим в админ интерфейс http://localhost:8000/admin.

start page

Добавляем суперпользователя и отвечаем на поставленные вопросы.

./manage.py createsuperuser

После авторизации попадаем на интерфейс администратора.

start page

Изменение стартовой страницы.

Создание приложения.

./manage.py startapp main

Подключение его в проект setting.py.

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

Создаем функцию в main/views.py, обслуживающую маршрут.

from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.

def index(request):
    return HttpResponse('Hello')

Импортируем эту функцию в urls.py и привяжем к ней стартовую станицу.

from main.views import index

urlpatterns = [
    path('', index),
    path('admin/', admin.site.urls),
]

Попробуем использовать шаблонизатор методом render.

def index(request):
    return render(request,'index.html',{'name': 'Dima'})

Создадим каталог для шаблонов в папке templates в корне проекта и в нем index.html.

<!doctype html>
<html lang="en">
  <head>
  </head>
  <body>
    <h1>Hello, world!</h1>
  </body>
</html>

Для того, чтобы сообщить Django где искать шаблоны, добавим путь к папке templates в settings.py.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        ...
    },
]

Установка bootstrap.

npm install bootstrap

Пример подключения стилей в шаблоне.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css">

Настройки проекта под данное подключение.

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "node_modules"),
]

Typescript. Начало работы.

Инициализация npm проекта.

npm init

Установка транспилятора

sudo npm install -g typescript

Установка и обновление nodejs и npm.

npm install npm@latest -g
sudo npm cache clean -f
sudo npm install -g n
sudo n stable

Проверка версии.

node -v

Создание конфигурационного файла.

Первая программа app.ts.

function greeter(person) {
    return "Hello, " + person;
}

greeter('Dima')

Компиляция.

tsc app.ts

Либо указывая полный путь.

./node_modules/.bin/tsc

Создание конфигурационного файла tsconfig.json

В этом файле определяются:

  • входная (корневая) директория проекта;

  • выходная директория;

  • опции компилятора;

  • определяются какие файлы включать и выключать из компиляции.

    { “compilerOptions”: { “module”: “commonjs”, “target”: “ES5”, “outDir”: “dist”, “rootDir”: “src” }, “exclude”: [ “node_modules” ] }

если вы указываете файл для компиляции явно то конфигурационный файл игнорируется!

Список всех настроек typescript

Перенесем app.ts файл в папку src.

Запуск транспилятора в режиме отслеживания изменений (watch).

tsc -w

Исключение и включение каталогов из процесса слежения (tsconfig.json).

{
"compilerOptions": {
    ....
},
"include": [
    "**/*"
],
"exclude": [
    "node_modules",
    "**/*.spec.ts"
]}

При этом приняты следующие условные обозначения.

    • любое кол-во символов, исключая разделитель каталогов

? - один любой символ, исключая разделитель каталогов

**/ - все подкаталоги

Полная версия

{
    "compilerOptions": {
        "module": "commonjs",
        "esModuleInterop": true,
        "target": "es6",
        "noImplicitAny": false,
        "moduleResolution": "node",
        "sourceMap": true,
        "outDir": "dist",
        "baseUrl": ".",
        "paths": {
            "*": [
                "node_modules/*"
            ]
        }
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "node_modules"
    ]
}

Определение типа передаваемого значения.

function greeter(person: string) {

Попытка передать неверный тип.

let user = [0, 1, 2];
document.body.innerHTML = greeter(user);

src/app.ts:7:35 - error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

Определение типа возвращаемого значения.

function greeter(person: string): number {
    return "Hello, " + person;
}   
src/app.ts:8:1 - error TS2322: Type 'number' is not assignable to type 'string'.

Модульность

Определим библиотечную функцию src/lib/function.ts.

export function sayHello( name ) {
    return `Hello {$name}`;
};

Импортируем ее в главном модуле app.js.

import { sayHello } from './lib/function';

console.log(sayHello());

Получаем ошибку в консоле.

app.js:2 Uncaught ReferenceError: exports is not defined

Установим jQuery.

npm i jquery @types/jquery --save

Пробуем импортировать.

import $ from "jquery";
console.log($);

Получаем ошибку.

Module '"/home/zdimon/Desktop/work/ts-gulp/node_modules/@types/jquery/index"' can only be default-imported using the 'esModuleInterop' flagts(1259)

Изменим импорт.

import * as $ from "jquery";

Или выставим esModuleInterop флаг в True в tsconfig.json

После компиляции получаем ошибку.

start page

Наш браузер не знает такой конструкции из модульной системы commonjs как require.

А откомпилированный файл ее содержит.

var $ = require("jquery");
console.log($);

Поэтому при компиляции необходимо использовать такой инструмент как browserify.

Он умеет преобразовывать ES6 в совместимый ES5.

Для компиляции удобно использовать менеджер задач gulp.

Устанавливаем gulp.

npm install --save gulp

Делаем простую задачу в файле gulpfile.js.

var gulp = require('gulp');
gulp.task('default', (done) => {
    console.log('Gulp task!!');
    done();
})

Запуск.

node node_modules/gulp/bin/gulp.js

Результат работы.

start page

Все API gulp сосоит из нескольких функций:

gulp.src - выбирает все файлы по маске из указанной директории

gulp.dest - создает поток для записи “ванильного” js объекта в папку

gulp.task - создает задачу

gulp.watch - отслеживает изменения в файлах

gulp.series - мы можем перечислять несколько функций, которые будут вызваны одна за другой.

Для последующей работы нам понадобятся следующие инструменты.

browserify - для исключение require из сборки (см. выше);

typescript - компилятор typescript

tsify - подобно аналогу gulp-typescript, предоставляет доступ к компилятору TypeScript;

vinyl-source-stream - преобразовывает “ванильный” вывод browserify в потоковый формат для последующей записи при помощи gulp.dest.

Устанавливаем.

npm install --save-dev browserify tsify vinyl-source-stream typescript

Скрипт сборки.

var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var tsify = require("tsify");

gulp.task('default', (done) => {
    return browserify({
        basedir: './src/client',
        debug: true,
        entries: ['index.tsx']
    })
    .plugin(tsify)
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(gulp.dest("dist/prod"));

})

У нас сборка содержит библиотеку jquery, однако мы может ее импортировать вручную.

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>

И так как мы установили прежде

npm install --save @types/jquery

Переменная $ у нас доступна глобально в скриптах и мы можем явно ее не импортировать и не включать jquery в сборку.

Обновление страницы браузера после компиляции.

Установим инструмент browser-sync

npm i browser-sync --save

Определим переменную.

const browserSync = require('browser-sync').create();

Вынесем компиляцию в отдельную функцию.

function compileTS() {

    return browserify({
        basedir: './src',
        debug: true,
        entries: ['index.ts']
    })
    .plugin(tsify)
    .bundle()
    .pipe(source('index.js'))
    .pipe(gulp.dest('dist'));
}

Вызовем ее вот так.

exports.default = gulp.series(
        compileTS
    );

В gulp.series мы можем перечислять несколько функций, которые будут вызваны одна за другой.

Определим функцию запуска сервера.

function startBrowserSync() {
    browserSync.init({
        server : {
            baseDir : '.'
        },
    });
}

Функцию перезагрузки.

function reload(cb) {
    browserSync.reload();
    cb();
}

Функцию отслеживания изменений.

function watch() {
    gulp.watch('src', gulp.series(compileTS,reload));
}

Объеденим все вместе.

exports.default = gulp.series(
        compileTS,
        gulp.parallel(startBrowserSync, watch)
    );
Задать вопрос, прокомментировать.