Is it Safe to Travel through Istanbul Airport?

Because of the global corona-virus epidemic, global measures are taken to higher levels. For this purpose, I tried to clarify this issue, which is wondered by those who are thinking of coming to Istanbul. I tried to answer the question of "Is it safe to travel through Istanbul airport".

Because airport and terminals are only a small part of any travel, being safe shouldn't mean anything in itself. You should also keep your distance after leaving the terminal building. Moreover, Airport to city transportation is another challenging. Considering this, I recommend Istanbul Private Transfer Expert for Istanbul airport to city transfers.

if Istanbul airport is safe to travel. Before Istanbul Airport, I should explain some criteria among the global aviation.

Human behaviour is the most influential factor for spreading COVID-19 virus. Therefore, it is essential to keep being attentive.

Global coroavirus aviation standards

What are the Global Standards for International Airports?

Airports Council International, ACI, is the only global trade representative of the world’s airports and they announced the international airports who accredited their health programme.
The programme promotes the maintains of safe and hygienic facilities.

Cleaning and disinfection, physical distancing, staff protection, physical layout, passenger communications and passenger facilities are included by subject.

Also, terminal access, check-in areas, security screening, boarding gates, lounges, retail, food and beverages, gate equipment such as boarding bridges, escalators and elevators, border control areas and facilities (in collaboration with authorities), baggage claim area and arrivals exit zones are included by region.

Which Airports in Turkey are Safe to Travel?

According to AIC, there are nearly 300 airports in the world are accredited to their health programme. From Turkey, those airports are on the list of Airports Council International:

You can see the official airport list of Airports Council International below.

Istanbul airport precautions

Is it Safe to Travel through Istanbul Airport?

It seems that precautions taken against spreading COVID-19 in Istanbul airport not only follows the international standards but also improve it with their implementations. Because Istanbul Airport is relatively new airport, this situation provides flexibility. Istanbul airport test center is allocated for COVID-19 related tests.

Where is Istanbul Airport Corona-virus Test Center?

The test center is located at the exit gate number 14 "Arriving Passenger".

How to test against Corona-virus in Istanbul Airport?

Here are the Istanbul Airport PCR Test Procedure:
If you want to be a Covid-19 PCR test, you can follow the steps below.


We might say that it is safe to travel through Istanbul airport. However, the unique context and precautions listed above only makes the airport safe. It is your responsibility to answer the question of "Is Istanbul airport safe to travel?". If you decided to arrive Istanbul airport, read the article of Istanbul airport to city guide.

Airport list which are accredited to ACI programme


References:

Free Design Resources and Graphic Design Tools

The collections of free design resources and graphic design tools. I listed many graphic design resources that make possible to generate and create useful graphics.


Free Design Resources Part I - Generator Apps

These tools generate design resources for you. They are simple tools but generate effective patterns and code. Those are free design resources that you can tweak an use them.

Advanced Blog Generator

CSS Shapes

Pre-made shapes that is completely written by CSS code.

Animista

Easily copy and paste the CSS animations.

Text Column Generator

Split your text through columns by CSS.

Text Shadow CSS Generator

Pre-made text shadows from Mixfont. Easily copy and paste the CSS code.

Text Shadow Generator

Clip Path Generator

Easily create a clip path by this free design generator from Uplabs.

CSS Stripes Generator

SVG Shape

A simple SVG shape generator with minimal options.

Animated Header

Animated Header

This advanced tool provides animated headers with rich customization options.

Glassmorphism Generator

free design resources - glassmorphism

I didn't like neuomorphism so much. However, this year's trend is awesome. Probably, you are familiar with it. Here the glassmorphism generator that produces CSS.

Get Waves

Get Waves is a web app that produce wave pattern in SVG format. Thus, you can manipulate them easily.

SVG Waves

Another generator that produces wave pattern in SVG or PNG formats.

Faux Code Generator

This app requires a link of any GitHub gist. When you provide the source code, the web app transforms it to a faux code graphics.

Neumorphism CSS Generator

free neuomorphism generator

This web app allows you to create neumorphism CSS code that you tweak visually.

Soft UI

Another free design resource that makes possible to build neumorphic style code.

Glitch Art

The glitch art generator produces glitch patterns.

Fancy Border Generator

free fancy border generator

This online design resources allows you to make custom shape borders.

Components.ai

This design resource actually a suit. It consists of many design generator that is produced by machine learning algorithms. Gradients, color scales, voronoi, and bootstrap color palette generator.

Material Shadow

It allows you to add shadows to your icons. You can also select predefined material icons.

Technology Bullshit Generator

If you need flashy words, then this app makes it for you. It create flashy but bullshit word generator.

Squircley

Squircley generate a shape neither square nor circle. You can tweak it as you want.

Shape Divider

It divides the shape 🙂 You realized that some kind of divided shapes are well suited on landing pages. You can do those kind of shapes with this design resource.

Blobs

Decorative blob generator tool.

Omatsuri Suite

Omatsuri is not a single graphic design tool. It is actually a free design resources suit. You can find many useful graphic design resources such as triangle generator, wave generator, color shades and color palette generators.

Blog Cover Generator

Easy blog post cover generator.

Patternico

A pattern generator.

Doodad

Yet another pattern generator

Tabbied

Doodle with generated patterns.

BG Jar

Very useful background pattern generator which can export your design in various formats such as CSS, SVG or PNG.


Free Design Resources Part II - Visual Content Creator Tools

Canva

free design resources - canva

Canva is the most popular and the most used graphic content creations site. It has both free and premium plans. If you need a quick visual content Canva is one of the best design resource.

Easil

Easil is another Canva alternative that has limited features for free plan.

Visme

Visme is an online tool that allows you to easily create info-graphics. Those are very useful for visual explanations and building back-links.

Glorify

Glorify is a Canva-like tool that specifically create graphics for different platforms such as Product Hunt, Shopify, Fiver etc...

Polotno Studio

Polotno Studio allows you to edit your graphics.

Projector

Projector is also another free graphic template design tool.

Taler

Taler is relatively new tool comparing with other free design resources. It is also powered by e-commerce platform Shopify.

Crello

It is very limited graphic design tool. Only 5 design downloads are permitted.

Artify

I personally like the illustration of Artify. Once in a while, It does not respond. However, It is now working. I should also mention that attribution is required.

Design AI

Design AI is another Canva alternative platform that has speech and video maker features.


Free Design Resources Part III - Prototyping and Graphic Editing Tools

Figma

free design resources - figma

Figma is awesome. It is a sketch alternative. Moreover, It is boosted by Web-Assembly technology that makes possible to do these stuff on your browser. It is great for teams and freelancers. It also allows you to graphically edit React components. In this way, Framer is a unique design tool.

Penpot

Penpot is an open-source free prototyping and design tool that is currently at alpha stage.

Framer

free design resources - framer

Framer stands out with its mobile and interaction prototype development. It has web version as long as MacOS versions. React developers may know Framer Motion library which is the product of Framer.

Lunacy

Lunacy is a desktop software created by Icons8. Because of the creator company, it has built-in assets. Currently only available for Windows.

Spline

One of the best tools of 2020. Spline allows you to create 3D geometry. Moreover, It has Linux support.


Free Design Resources IV - Design System Tools

Toolabs Design System

Toolabs is a very intuitive tools that allows you to create your design system and export it with various formats such as CSS, JSON etc.. Also, It creates a web page for your design system that you can access and share it easily.

Frontify

Frontify actually is more than a design system tool. It is a complete brand design suite. It has a free plan for freelancers. You can create your design guideline and design system. Frontify also allows you to create a web page in order to access and share your guideline. Moreover, you can develop and design a user-interface component and share the code easily. A sample guideline page can be seen below:

Free Design Resources - Frontify

Diez

Tokens are great when the case is design. Diez is a tool that is specialized in creating design tokens.

ZeroHeight

You can create your design guidelines with Zeroheight and make it single source of truth. Because it includes both design and code assets, communication with designers and developers becomes less problematic.


Free Design Resources V - Miscellaneous

Design Lobby

It is nice looking asset manager. You can deploy your design assets such as typefaces, icons, images and colors. Currently in a beta phase.

Squoosh

Squoosh is a one page web app that is the easiest way to compress images. As we know, Google stated that fast opening is an important factor when ranking websites. Therefore, image compression is a must for websites that is aiming to rank higher. Considering the situation, Squoosh is an important free design resource.

Scrollbar Designer

Design your page's scrollbar. It should be also noted that it doesn't work on Firefox. You can accomplish it via JavaScript.

It will be updated as soon as possible.

Hosted Confluence with Custom Domain

One of our customers from Istanbul Airport Transfer Expert and Istanbul Cruise Port Transfer ask the possibility of using Atlassian Confluence as a self-hosted wiki program. We look for solutions for a while. Later on, we discovered Cloudron app. In this article, We'll install Confluence with a custom domain on our servers.

What is Confluence?

Confluence is a team collaboration and wiki software developed by Australian software company Atlassian.
It is a web-based application and written in Java programming language.It was released in 2004 (Voav) as an enterprise knowledge management software.

Confluence Screenshots

You can use it as a team collaboration app, wiki, knowledgebase, blog, intranet etc.

If you read my articles written in Turkish, you realized that talented editor is a must for me in any platform I wrote. The editor of Confluence is one of the best editor in the universe. It has really advanced permission level. You can create many workspaces.

However, Atlassian Cloud doesn’t allow us to use our custom domains and managed Confluence solutions is a bit complicated.

Fortunately, Cloudron made it easier for us to use it on our own servers. By doing this, we can use our own custom domains with Atlassian Confluence app.

How much does it cost to use Self-Hosted Confluence?

Confluence requires at least 4 GB RAM. Thus, the most expensive cost will the cloud instance.Cloudron is free for personal usage up to 2 apps which is completely sufficient for us.
Therefore, the cost of using Confluence with a custom domain will be:

I'll share a referral links below that gives you some amount of free credits. Thus, It is free to follow this guideline.

What are the requirements?


Step 1 - Create Droplet with Cloudron

Our Confluence app will be hosted on the droplet which we will create now. A Droplet is basically a virtual server in Digital Ocean.

I'm assuming that you have created an DA account and created a project. Now, we'll create a droplet with Cloudron app installed.

On the left side, you'll find Marketplace link under the Discover section.

Click the marketplace link.  Search and select Cloudron.

Cloudron on Digital Ocean

Click Create Couldron Droplet button.

Create Cloudron Droplet

Now, you'll see the droplet settings page. As I told you before, Confluence requires minimum 4 GB RAM. Therefore, we should minimum select Basic plan which costs $20/month. Also, we'll choose the closest data-center to us and create a password as an authentication method.

Cloudron droplet settings

At the bottom of the page, we'll click the Create Droplet button. It will start the installation of cloud instance and Cloudron application.


Step - 2) Initial Configurations

We are going to make some domain adjustments. There are two cases for your domain name provider.

In either case, I'll follow the manual method that fits every case.

DNS Settings

First, visit the project page on Digital Ocean. If any IP number assigned to your instance, note it down. Otherwise, wait till the assignment. For example mine is 46.101.148.85.

droplet-ip

To make illustration, Let say we have a domain livicomturkiye.com. We also decided to use a subdomain for the Confluence app, let's say notes.livicomturkiye.com.

Second, Whether your DNS provider is DA or not, visit your domain name provider's website. Go to DNS management page of your domain name.
Add these two 'A records' that target the IP number we saved above.

HostTarget
notes46.101.148.85
my.notes46.101.148.85

First one is the subdomain name you use with Confluence. Second one is the cloudron panel with a prefix of my.
Save the records.

You can control whether your domain is pointing to correct IP by visiting dnschecker.org. If the A record points to the correct IP, you can proceed. DNS propagation can take some time. Therefore, this process can took time.

Cloudron settings

Open your browser and paste the IP number of your instance on a new page.

browser-security-warning

(Note: We have not any secure certificate now.Therefore, your browser will warn you about the privacy. This means your connection is not encrypted end-to-end. Open the advanced settings and proceed with unsafe method.)

You'll see Cloudron setup page.

cloudron-domain-setup

Click Next. Now, Cloudron will start to make proper internal configurations. Whet it finishes, you'll fill the admin form.

Confluence Installation

If we did everything right, we see an empty Cloudron page.
On the upper right menu, click App Store. Before this, you fill the login form of Cloudron.

confluence-installed-cloudron

Write your credentials and login.
Search Confluence and install it.


Step - 3) Confluence Settings

I assume that all the settings properly configured. Now, click Confluence app on Cloudron page.

A setup page welcomes us. Follow the steps below:

Select Product Installation. If you need Confluence Questions or Confluence Team Calendars, please also select them. Click Next.

Press Get an evaluation license link and get the license for Confluence Server. Click Next.

If you have a database choose My own database. Otherwise, you can use built-in database as a temporary solution. Click Next.

Wait until the database settings are done. Then, create an empty site.

Fill the System Administrator Account.

Give your space a name. For example: "Personal Wiki".

confluence-empty-page

Now, you can use Atlassian Confluence on your domain. You can create a redirection to your space or make your space public. Just configure them on General Configuration.

Django and Modern JS Libraries - Svelte

(Note:This article is originally published while building the websites of Istanbul Airport TransferIstanbul Cruise Port Transfer)


In the previous part, we built a Django backend and GraphQL API. In this part, we will integrate the Django project with Svelte.

Thus, it's necessary to follow Django and Modern JS Frameworks - Backend.


What is Svelte and How it differs from React?

I like Python and its ecosystem. I also like Just-In-Time compilers and language supersets like Cython, which really boosts Python performance. When I learned that JavaScript is an interpreted language, I tried to look Cython equivalent of it.

Because of different browser compilers, I couldn’t find what I want and it made a disappointment. Maybe it is the reason I feel the excitement when I give Svelte a chance.

If you didn't try Svelte before, you may give it a chance. Svelte's interactive API and tutorials are also worth to praise. Being familiar with Svelte API and Tutorials is definitely recommended.

When I’m talking about Svelte, I’m strictly speaking about Svelte 3. It is another JavaScript library written by Rich Harris. What makes Svelte special is:

Yes, React was revolutionary. However, how many times we have to deal with virtual DOM synchronization problems or the extra burden for even very small operations are the other side of the medallion.


Svelte Configuration with Webpack from Scratch

Step - 1: Configuring the development environment

(Note: if you already installed the node, you can skip this part)

We will use Node backend for the development environment.

Therefore, we need to install Node and Node package manager npm.

To prevent potential dependency problems, we will create a clean node environment.

I will use NVM which is a Node version manager, and it allows us to create isolated Node environments.

In your terminal, run the code below.

Setup Node Environment with NVM

In your terminal, run the code below.

# install node version manager wget -qO- <https: raw.githubusercontent.com="" nvm-sh="" nvm="" v0.35.3="" install.sh=""> | bash # check installation command -v nvm # should prints nvm, if it doesn't, restart your terminal </https:>
Code language: Bash (bash)
# install node # node" is an alias for the latest version # use the installed version nvm use node nvm install node
Code language: Bash (bash)

Now we can create a frontend directory in the Django project. Go to the root directory of the project. 'backend/'

In your terminal copy and paste the code.

# create frontend directory mkdir FRONTEND cd FRONTEND # now your terminal directory should be # backend/FRONTEND # create a node project npm init # you may fill the rest
Code language: PHP (php)

Now we can install front-end and development libraries.

# install svelte and other libs npm install --save-dev svelte serve cross-env graphql-svelte # install webpack and related libs npm install --save-dev webpack webpack-cli webpack-dev-server # install webpack loaders and plugins npm install --save-dev style-loader css-loader svelte-loader mini-css-extract-plugin npm install --save node-fetch svelte-routing
Code language: PHP (php)

Update package.json scripts part as below. Your file should look like this and ignore the versions.

{ "name": "django-svelte-template", "description": "Django Svelte template. ", "main": "index.js", "scripts": { "build": "cross-env NODE_ENV=production webpack", "dev": "webpack-dev-server --content-base ../templates" }, "devDependencies": { "cross-env": "^7.0.2", "css-loader": "^3.5.3", "graphql-svelte": "^1.1.9", "mini-css-extract-plugin": "^0.9.0", "serve": "^11.3.1", "style-loader": "^1.2.1", "svelte": "^3.22.3", "svelte-loader": "^2.13.6", "webpack": "^4.43.0", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.11.0" }, "dependencies": { "node-fetch": "^2.6.0", "svelte-routing": "^1.4.2" } }
Code language: JSON / JSON with Comments (json)

Let’s create application necessary files and folders for Svelte. In the root directory of the project 'backend/’ , open your terminal.

# create HTML file of the project cd templates touch index.html # change directory to backend/FRONTEND cd ../FRONTEND mkdir src touch index.js touch webpack.config.js # change directory to backend/FRONTEND/src cd src touch App.svelte touch MovieList.svelte touch MoviePage.svelte touch api.js
Code language: PHP (php)

Step 2 - Webpack configuration

What is webpack ?

Webpack is a module bundler and a task runner.

We will bundle all our JavaScript applications including CSS styling into two JavaScript files, if you prefer you can output only one file.

Because of the rich plugins, you can also do many things with Webpack like compressing with different algorithms, eliminate unused CSS code, extracting your CSS to different files, uploading your bundle to cloud providers like S3, etc…

I made two different Webpack settings in one file.

One is for a development environment, and the other one is for a production environment.

Also, note that we do not optimize these configurations.

Copy/Paste the following code into the webpack.config.js file.

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); const mode = process.env.NODE_ENV || 'development'; const isEnvProduction = mode === 'production'; const productionSettings = { mode, entry: { bundle: ['./index.js'] }, resolve: { alias: { svelte: path.resolve('node_modules', 'svelte') }, extensions: ['.mjs', '.js', '.svelte'], mainFields: ['svelte', 'browser', 'module', 'main'] }, output: { path: path.resolve(__dirname, '../static'), filename: 'js/[name].js', chunkFilename: 'js/[name].[id].js' }, optimization: { minimize: true, runtimeChunk: false, }, module: { rules: [ { test: /\.svelte$/, use: { loader: 'svelte-loader', options: { emitCss: true, hotReload: true } } }, { test: /\.css$/, use: [ /** * MiniCssExtractPlugin doesn't support HMR. * For developing, use 'style-loader' instead. * */ MiniCssExtractPlugin.loader, 'css-loader' ] } ] }, devtool: false, plugins: [ new MiniCssExtractPlugin({filename: '[name].css'}) ], }; const devSettings = { mode, entry: { bundle: ['./index.js'] }, resolve: { alias: { svelte: path.resolve('node_modules', 'svelte') }, extensions: ['.mjs', '.js', '.svelte'], mainFields: ['svelte', 'browser', 'module', 'main'] }, output: { publicPath: "/", filename: 'static/js/bundle.js', chunkFilename: 'static/js/[name].chunk.js', }, devtool: 'source-map', devServer: { historyApiFallback: true, stats: 'minimal', }, module: { rules: [ { test: /\.svelte$/, use: { loader: 'svelte-loader', options: { emitCss: true, hotReload: true } } }, { test: /\.css$/, use: [ /** * MiniCssExtractPlugin doesn't support HMR. * For developing, use 'style-loader' instead. * */ 'style-loader', 'css-loader' ] } ] }, mode, plugins: [ ], } module.exports = isEnvProduction ? productionSettings : devSettings;
Code language: JavaScript (javascript)

Step 3 - Create a Single-Page-App witth Svelte

First, fill the 'backend/FRONTEND/index.js’.

import App from './src/App.svelte'; const app = new App({ target: document.body, }); window.app = app; export default app;
Code language: JavaScript (javascript)

Next, fill the ‘App.svelte’ file with proper logic.

<!-- App.svelte --> <script> import { Router, Link, Route } from "svelte-routing"; import MovieList from "./MovieList.svelte"; import MoviePage from "./MoviePage.svelte"; export let url = ""; </script> <Router url="{url}"> <nav class="navbar"> <Link to="/">Home</Link> </nav> <div class="main-container"> <Route path="movie/:slug" component="{MoviePage}" /> <Route path="/"><MovieList /></Route> </div> </Router> <style> .navbar { background-color:rgba(0,0,0,0.6); display: flex; padding: 16px 64px; font-weight: bold; color:white; } .main-container { margin-top:32px; display:flex; justify-content: center; align-items: center; background-color: rgba(0,0,0, 0.15); } </style>
Code language: HTML, XML (xml)

Before routing pages, I will first write the client-side queries. Please open api.js and copy/paste the code below.

<code>import { GraphQLProvider, reportCacheErrors } from "graphql-svelte"; const client = GraphQLProvider({ url: 'http://127.0.0.1:8000/graphql', headers: () => ({ "content-type": "application/json", Accept: 'application/json' }) }) client.graphql.on('cache', reportCacheErrors) // our first query will requests all movies // with only given fields // note the usage of string literals (`) export const MOVIE_LIST_QUERY = `query movieList{movieList{name, posterUrl, slug}} ` // Note the usage of argument. // the exclamation mark makes the slug argument as required // without it , argument will be optional export const MOVIE_QUERY = `query movie($slug:String!){ movie(slug:$slug){ id, name, year, summary, posterUrl, slug } } ` // This is generic query function // We will use this with one of the above queries and // variables if needed export async function get(query, variables = null) { const response = await client.get({ query , variables }) console.log("response", response); return response } </code>
Code language: JavaScript (javascript)

Now, route pages: MovieList.svelte will be shown on the homepage as we defined in the above. If the user clicks any movie card, then MoviePage.svelte file will be rendered.

Fill the MovieList.svelte.

<script> import { Router, Link, Route } from "svelte-routing"; import { get, MOVIE_QUERY, MOVIE_LIST_QUERY } from "./api.js"; var movielist = get(MOVIE_LIST_QUERY); </script><script> import { Router, Link, Route } from "svelte-routing"; import { get, MOVIE_QUERY, MOVIE_LIST_QUERY } from "./api.js"; var movielist = get(MOVIE_LIST_QUERY); </script> <div class="wrapper"> <!-- promise is pending --> {#await movielist} loading <!-- promise was fulfilled --> {:then response} {#if response.data.movieList.length > 0} {#each response.data.movieList as movie} <div class="card"> <Link to={`/movie/${movie.slug}`}> <img class="poster" alt={movie.name} src={movie.posterUrl} /> <p class="movie-title">{movie.name}</p> </Link> </div> {/each} {/if} <!-- promise was rejected --> {:catch error} <p>Something went wrong: {error.message}</p> {/await} </div> <style> .wrapper { width:100%; height: auto; display:flex; flex-direction: row; flex-wrap: wrap; } .card { box-sizing: border-box; position: relative; width:200px; height:auto; margin:16px; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 4px rgba(0,0,0,0.25); } .poster { width:100%; height:auto; cursor: pointer; } .movie-title { padding:4px 8px; font-weight: bold; text-decoration: none; cursor: pointer; } </style>
Code language: HTML, XML (xml)

Also, fill MoviePage.svelte according to this.

<code><code>import { Router, Link, Route } from "svelte-routing"; import { get, MOVIE_QUERY, MOVIE_LIST_QUERY } from "./api.js"; var movielist = get(MOVIE_LIST_QUERY); </script> <div class="wrapper"> <!-- promise is pending --> {#await movielist} loading <!-- promise was fulfilled --> {:then response} {#if response.data.movieList.length > 0} {#each response.data.movieList as movie} <div class="card"> <Link to={`/movie/${movie.slug}`}> <img class="poster" alt={movie.name} src={movie.posterUrl} /> <p class="movie-title">{movie.name}</p> </Link> </div> {/each} {/if} <!-- promise was rejected --> {:catch error} <p>Something went wrong: {error.message}</p> {/await} </div> <style> .wrapper { width:100%; height: auto; display:flex; flex-direction: row; flex-wrap: wrap; } .card { box-sizing: border-box; position: relative; width:200px; height:auto; margin:16px; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 4px rgba(0,0,0,0.25); } .poster { width:100%; height:auto; cursor: pointer; } .movie-title { padding:4px 8px; font-weight: bold; text-decoration: none; cursor: pointer; } </style> </code> </code>
Code language: JavaScript (javascript)

Start the Svelte App in Development Environment

In the development environment, we will run two different servers.

When our Svelte app is running, it requests data from the Django server.

After the response comes, the Webpack Development server renders the page with proper data. This is only for the development stage.

When we finish the front-end development, we will build and bundle a client-side app.

After then we will start the Django server, and it will be the only server we will use in the production environment, as I promise before.

Execute the below command and make the Django server ready for front-end requests.

# execute it on the root folder of Django 'backend/' python manage.py runserver
Code language: PHP (php)

Open another terminal and change the directory to the ‘backend/FRONTEND’

# On another terminal npm run start
Code language: PHP (php)

When Svelte app successfully compiled, open your browser ‘localhost:8080/’.

You should see similar screen like the image below.

MovieList.svelte will render the screen

MoviePage.svelte screen will render this if the user clicks any movie card

What will be happened at the moment?

At this moment, “/“ root page will be rendered. Because of our routing configurations, MovieList.svelte file will be rendered first. If the user clicks any film card, then the MoviePage.svelte file will be rendered regarding its slug value.

We succesfully integrated Django and Svelte. Now make the production build.


Django and Svelte Integration in Production Environment

Now you can stop webpack server while keeping the Django server alive.

In the backend/FRONTEND/ directory, execute the command below.

npm run build

This will build and bundle all your Svelte app in bundle.js file. When bundling process is over, go to the URL of Django server in your browser. --> “127.0.0.1:8000/”

You should see the same screens above. Also note the static folder which has new files coming from webpack bundling.


FINISHED


Django and Modern JS Libraries - React

In the previous part, we built a Django backend and GraphQL API that is responsible for the communication of the Django project and react app. In this part of the tutorial, we will create a single page application with React from scratch.

We will bundle our application with webpack and we will not use create-react-app boilerplate

Create React App from Scratch

Step - 1: Configuring development environment

(Note: if you already installed the node, you can skip this part)

We will use Node backend for the development environment.

Therefore we need to install Node and Node package manager npm. In order to prevent possible dependency problems, we will create a clean node environment.

I will use NVM which is a Node version manager and it allows us to create isolated Node environments.

In your terminal, run the code below.

# install node version managerwget -qO- <https: raw.githubusercontent.com="" nvm-sh="" nvm="" v0.35.3="" install.sh=""> | bash </https:>
Code language: HTML, XML (xml)
# check installation command -v nvm # should prints nvm, if it doesn"t # you can restart your terminal
Code language: PHP (php)
# install node # node" is an alias for the latest version nvm install node # use the installed version nvm use node # prints Now using node v..
Code language: PHP (php)

Now we can create a frontend directory in the Django project.

Go to the root directory of the project. 'backend/'

In your terminal copy and paste the code.

# create frontend directory mkdir FRONTEND cd FRONTEND #in backend/FRONTEND create a Node project npm init # you may fill the rest
Code language: PHP (php)

Now we can install Javascript dependencies such as React and API related to other libraries.

# add core react library npm install react react-dom react-router-dom # add graphql client-side framework of Apollo and parser npm install apollo-boost @apollo/react-hooks graphql graphql-tag # -- DEVELOPMENT PACKAGES--- # add babel transpiler npm install --save-dev @babel/core @babel/preset-env @babel/preset-react # add webpack bundler npm install --save-dev webpack webpack-cli webpack-dev-server # add webpack loaders and plugins npm install --save-dev babel-loader css-loader style-loader html-webpack-plugin mini-css-extract-plugin postcss-loader postcss-preset-env
Code language: PHP (php)

If everything goes well, we can create necessary files.

# create source folder for client side code mkdir src # our react app's root file touch index.js #create webpack config file touch webpack.config.js # get into src folder cd src # create HTML entrypoint for React development touch index.html
Code language: PHP (php)
# our app file and styling touch App.js // Screens touch MovieList.js touch MoviePage.js # for styling touch App.css
Code language: PHP (php)

All npm packages contain a file that holds metadata about the app. This file is a package.json file.

You should update the package.json file.

Edit the scripts section and add Babel presets and postcss configurations.

{ "scripts": { "start": "webpack-dev-server --open --hot --mode development", "build": "webpack --mode production" }, "babel": { "presets": [ "@babel/preset-env", "@babel/preset-react" ] }, "postcss": { "plugins": { "postcss-preset-env": {} } }, }
Code language: JSON / JSON with Comments (json)

Step 2 - Webpack configuration and index.html file

What is webpack ?

Webpack is a module bundler and a task runner.

We will bundle all our JavaScript applications including CSS styling into two JavaScript files, if you prefer you can output only one file.

Because of the rich plugins, you can also do many things with Webpack like compressing with different algorithms, eliminate unused CSS code, extracting your CSS to different files, uploading your bundle to cloud providers like S3, etc…

I made two different Webpack settings in one file.

One is for the development environment, and the other one is for a production environment.

Also, note that we do not optimize these configurations.

Copy/Paste the following code into webpack.config.js file.

const path = require("path"); const HtmlWebPackPlugin = require("html-webpack-plugin"); // checks if it is production bundling or development bundling const isEnvProduction = process.argv.includes("production") // our JS root file const entrypoint = './index.js' const productionSettings = { mode: "production", entry: entrypoint, output: { // output directory will be the root directory of django path: path.resolve(__dirname, '../'), // this is the bundled code we wrote filename: 'static/js/[name].js', // this is the bundled library code chunkFilename: 'static/js/[name].chunk.js' }, optimization: { minimize: true, splitChunks: { chunks: 'all', name: true, }, runtimeChunk: false, }, devServer: { historyApiFallback: true, stats: 'normal', }, module: { rules: [ { loader: 'babel-loader', test: /\.js$|jsx/, exclude: /node_modules/}, { test: /\\.css$/i, use: [ // IMPORTANT => don't forget `injectType` option // in some cases some styles can be missing due to // inline styling. { loader: 'style-loader', options: { injectType: 'styleTag' } }, "css-loader" ], }, ] }, plugins: [ new HtmlWebPackPlugin({ // ENTRYPOINT - this is where webpack read our app for bundling template: "./src/index.html", // OUTPUT FILE // this is emitted bundle html file // ---------------------------------- // django will use this as template after bundling // ----------------------------------- filename:"./templates/index.html" }), ] }; const devSettings = { mode: "development", entry: entrypoint, output: { path: path.resolve(__dirname, './build'), publicPath: "/", filename: 'static/js/bundle.js', chunkFilename: 'static/js/[name].chunk.js', }, devtool: 'inline', devServer: { historyApiFallback: true, contentBase: './dist', stats: 'minimal', }, module: { rules: [ { loader: 'babel-loader', test: /\.js$|jsx/, exclude: /node_modules/}, { test: /\.css$/i, use: [ //{loader: MiniCssExtractPlugin.loader, options: { // //your styles extracted in a file for production builds. // //hmr: isEnvDevelopment, // }, // }, // IMPORTANT => don't forget `injectType` option { loader: 'style-loader', options: { injectType: 'styleTag' } }, "postcss-loader" //"css-loader" //{ loader: 'sass-loader' }, ], }, ] }, plugins: [ new HtmlWebPackPlugin({ template: "./src/index.html", }) ] }; module.exports = isEnvProduction ? productionSettings : devSettings;
Code language: JavaScript (javascript)

When we are developing frontend, our React app renders all our JavaScript code to this HTML file in the src folder.

Also, when we build our code for production (bundling), Webpack will use this HTML as a template.

It is important to say that Django will not use this HTML file. This is the HTML entry point of webpack. Django will use the output of the webpack bundle.

Update your index.html file.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Django-React Integration Tutorial"/> <title>Django React Integration</title> </head> <body> <div id="root"></div> </body> </html>
Code language: HTML, XML (xml)

Step - 3 Create the React app

The index file is the root file of our app, meaning that all our codes will be connected to this root file.

The other tutorials or each boilerplate use this file for only render function of ReactDOM and leave it small and clear.

Writing this index file as it is is a totally a choice.

What we will do is as follows: We will create an Init component that will initialize the API framework (Apollo) and routing library (react-router-dom).

We will wrap our App.js file with the API framework so that all our components will be in the context of API.

The Apollo Provider expects an Apollo client.

The Apollo client has the information of the requested address, which is the address of our Django server.

After then we will wrap our App file again with the router component, namely Browser Router. This makes our app a single-page-application.

Thus, we make routing without rendering all the pages when the URL of the address bar changes.

At the end of the file, you will see the render function of ReactDOM which accepts our root component, which is the Init component in our case, and the DOM element that our app will be rendered in there.

Update your index.js file as follows.

import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { BrowserRouter } from "react-router-dom" import ApolloClient from 'apollo-boost'; import { ApolloProvider } from '@apollo/react-hooks'; /* our frontend api client will make request to the adress we define in the first part. */ const apiclient = new ApolloClient({ uri: '<http: 127.0.0.1:8000="" graphql="">', }); const Init = () => ( <apolloprovider client="{apiclient}"> <browserrouter> <app> </app></browserrouter> </apolloprovider> ) ReactDOM.render( <init>, document.getElementById('root')) </init></http:>
Code language: JavaScript (javascript)

Now, we are ready to create our simple movie app.

Our app has two different screens:

Now update your App.js file.

import React from "react"; import { Route, Switch, Link } from "react-router-dom" // UI Screens we will define later import MoviePage from "./MoviePage.js" //New import MoviePage from "./MoviePage.js" //New import "./App.css" const App = () => { return ( <div className="App"> <Switch> <Route exact path="/" component={MainPage} /> {// colon before slug means it is a dynamic value // that makes slug parameter anything // like: /movie/the-lighthouse-2019 or /movie/anything // as long as slug matches with database. } <Route exact path="/movie/:slug" component={MoviePage} /> </Switch> </div>) } export default App
Code language: JavaScript (javascript)

Let me explain what that code means

When a user first opens our page, the switch component from react-router-dom will look at the URL. Then try to match the path of route components with this URL, if any, then the matched component in the route will be rendered.

Step - 4 Create page components and styling

The MovieList component will be shown on the landing page. Copy/Paste to "MovieList.js" file.

import React from "react"; import gql from "graphql-tag"; // our first query will requests all movies // with only given fields // note the usage of gql with 'jsvascript string literal' export const MOVIE_LIST_QUERY = gql` query movieList{ movieList{ name, posterUrl, slug } } ` const MovieList = (props) => { const { loading, error, data } = useQuery(MOVIE_LIST_QUERY); // when query starts, loading will be true until the response come. // At this time this will be rendered on screen if (loading) return <div>Loading</div> // if response fail, this will be rendered if (error) return <div>Unexpected Error: {error.message}</div>//if query succeed, data will be available and render the data return( <div classname="main-page"> {data && data.movieList && data.movieList.map(movie => ( <div classname="movie-card" key="{movie.slug}"> <img classname="movie-card-image" src="{movie.posterUrl}alt={movie.name" +="" "="" poster"}title="{movie.name" poster"}=""> <p classname="movie-card-name">{movie.name}</p> <link to="{`/movie/${movie.slug}`}" classname="movie-card-link"> </div>)) } </div>) } export default MovieList
Code language: PHP (php)

MoviePage component will show more details than the list view but only information about a specific movie.

Copy and paste the code MoviePage.js file.

import React from "react"; import gql from "graphql-tag"; // Note the usage of argument. // the exclamation mark makes the slug argument as required // without it , argument will be optional export const MOVIE_QUERY = gql` query movie($slug:String!){ movie(slug:$slug){ id, name, year, summary, posterUrl, slug } } `const MoviePage = (props) => { // uncomment to see which props are passed from router //console.log(props) // due to we make slug parameter dynamic in route component, // urlParameters will look like this { slug: 'slug-of-the-selected-movie' } const urlParameters = props.match.params const { loading, error, data } = useQuery(MOVIE_QUERY, { variables:{slug:urlParameters.slug} }); if (loading) return <div>Loading</div>if (error) return <div>Unexpected Error: {error.message}</div> return ( <div classname="movie-page"> <link to="/" classname="back-button">Main Page {data && data.movie && <div classname="movie-page-box"> <img classname="movie-page-image" src="{data.movie.posterUrl}alt={data.movie.name" +="" "="" poster"}title="{data.movie.name" poster"}=""> <div classname="movie-page-info"> <h1>{data.movie.name}</h1> <p>Year: {data.movie.year}</p> <br> <p>{data.movie.summary}</p> </div> </div>} </div>) } export default MoviePage
Code language: PHP (php)

Add some styling: update App.css.

html, body { width:100vw; overflow-x: hidden; height:auto; min-height: 100vh; margin:0; } .App { position: absolute; left:0; right:0; display: flex; min-width: 100%; min-height: 100vh; flex-direction: column; background-color: #181818; /*font-family: "Open Sans", sans-serif;*/ font-size: 16px; font-family: sans-serif; } /* MAIN PAGE */ .main-page { position: relative; display: flex; flex-wrap: wrap; min-height: 40vh; background-color: #3f3e3e; margin:10vh 5vw; border-radius: 6px; } /* MOVIE CARD */ .movie-card { position: relative; width:168px; height:auto; background: #f1f1f1; border-radius: 6px; margin:16px; box-shadow: 0 12px 12px -4px rgba(0,0,0, 0.4); } .movie-card:hover { box-shadow: 0 12px 18px 4px rgba(0,0,0, 0.8); } .movie-card-image { width:168px; height:264px; border-top-left-radius: 6px; border-top-right-radius: 6px; } .movie-card-name { text-align: center; margin: 0; padding: 8px; font-weight: bold; } .movie-card-link { position: absolute; top:0; left:0; right: 0; bottom: 0; } /* MOVIE PAGE */ .back-button { position: absolute; left:10px; top:10px; width:120px; padding: 8px 16px; text-align: center; background: #f1f1f1; color:black; font-weight: bold; cursor:pointer; } .movie-page { position: relative; display: flex; flex-direction: column; justify-content: center; align-items: center; flex-wrap: wrap; min-height: 80vh; margin:10vh 10vw; border-radius: 6px; } .movie-page-box { position: relative; display: flex; height:352px; background-color: #f1f1f1; } .movie-page-image { width:280px; height:352px; } .movie-page-info { position: relative; display: flex; flex-direction: column; height:352px; width: auto; max-width: 400px; padding: 16px 32px; }
Code language: CSS (css)

https://i2.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/single-page-django-react-app-final.jpg?ssl=1

Finally, Start Django-React App

Development Environment

In the development environment, we will run two different servers.

One is the Django server for backend, and the other one is the Webpack server for frontend development.

In the production environment, We will only run one Django server as I promise.

Go to the root folder of the Django project. 'backend/'.

Execute the below command and make the Django server ready for frontend requests.

python manage.py runserver
Code language: CSS (css)

Open another terminal and go to FRONTEND directory. ‘backend/FRONTEND’

npm run start

You will see those screens.

https://i2.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/movie-list-react.jpg?ssl=1
https://i0.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/movie-page-react.jpg?ssl=1

Django and React Successfully Integrated

We created a simple single-page-application. Now, the last part of this tutorial will be made this app works seamlessly with our Django project.

Now you can stop the webpack server with the corresponding terminal screen.

The Final Part - Production Build of Django and React

Now, We can build our app for the production environment. Go to the FRONTEND directory and execute the build command.

npm run build

When the build process is done, there will be two Javascript files in the backend/static folder:

Also, check the backend/templates folder and you will see other index.html files.

This is the HTML file that Django will use.

I made this graphic in order to show webpack bundling process and how our app will use output files.

https://i0.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/webpack-process.jpg?ssl=1

https://github.com/canburaks/django-and-modern-js-libraries

Django and Modern JS Libraries - Back-end

Preliminary Information About the Tutorial?

What is this tutorial about?

Django and Modern JS Libraries will be a tutorial series that integrates Django and contemporary frontend solutions such as React and Svelte. Another framework/library integrations are also planning in the future.

The Project Description

There are 2 projects and 3 articles in this series:

What are the requirements to follow?

Motivation

Python is my first programming language. When we were making a movie recommendation engine, we must integrate it with Facebook’s React library because we want it to be a single page application.

My level of knowledge about Javascript was at the introduction level. Proficient in an unfamiliar programming language takes some time.

Also, I like the Python ecosystem because of the excellent data science libraries, and giving up from Python was never a choice.

To sum up, it really took some time to integrate Django and React. When I recently published my development blog, I edited and update old articles.

During this time, another front-end library was released, and it excited me a lot: Svelte. I also added an integration article with Svelte and Django. I hope that this article series will help newcomers a bit to solve their problems.

General Information

What is a Single Page Application?

https://i1.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/architecture-of-single-page-app.jpg?ssl=1

In classic web pages, all HTML, CSS, and JS code are arranged and transferred by the server in a render-ready form. When a browser receives the code, it immediately renders elements on a screen. If a user clicks a link, then the browser makes another request to the server. The server will make all the logical operations and respond with another render-ready code.

In modern client-side apps, some logical operations are handled by Javascript code which is executed in the browser of users. Because of this, servers send all the website code in the first request. Thus, browsers need extra time for the first contentful painting.

Except for the first loading, client-side apps works faster and feels more native because some actions are done immediately on the browser and I/O operations can be done via asynchronous behavior of Javascript.

Therefore, users still see your app rather than a blank white page.

Browsers are amazing and capable of many impressive things.

Because of this capability, handling resource-heavy operations in the user’s browser can be a suitable alternative.

Otherwise, those operations make our server busy and can increase the bill.

Anyone who slaps a ‘this page is best viewed with Browser X’ label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network. ~ Tim Berners-Lee


Setting up the Django Back-end

Step-1: Create a Django project from scratch

https://i1.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/single-page-django.jpg?ssl=1

Let’s create a virtual environment fora clean setup.

This virtual environment will be an active environment for all three articles.

python3 -m venv tutorial-env <em># activate</em> source ./tutorial-env/bin/activate
Code language: HTML, XML (xml)

Install Django and dependencies

<em># install our dependencies</em> pip install ipython django django_extensions django-cors-headers "graphene-django>=2.0" <em>#create a django project</em> django-admin startproject djangoproject <em># change directory</em> cd djangoproject <em># create templates directory</em> mkdir templates <em># create static folder</em> mkdir static <em># create utils folder for initial data</em> mkdir utils
Code language: HTML, XML (xml)

Step - 2: Configuring and running

Update your ****'djangoproject/djangoproject/settings.py’ file. Extra settings are labeled as ’New …’.

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', "django_extensions",<em># New! (useful extension)</em> 'graphene_django', <em># New! (for graphql communication)</em> 'corsheaders', <em># New! (for cors request in dev env)</em> ] <em># New (for improved interactive shell)</em> SHELL_PLUS = "ipython" <em># New (it allows webpack development server to make cross origin request)</em> CORS_ORIGIN_WHITELIST = ( '<http://localhost:8080>', ) MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'corsheaders.middleware.CorsMiddleware', <em># New Add this</em> 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': (os.path.join(BASE_DIR, 'templates'),), <em># New</em> 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] <em>#New </em> STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
Code language: PHP (php)

Before starting our project, we should first make database migration. After, we will run our server and will see that is working.

<em># create migration for django-orm</em> python manage.py migrate
Code language: HTML, XML (xml)

Now, if everything goes well, Django server will start. You can open your browser and check the address 127.0.0.1:8000 You will see a screen like that:

https://i2.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/brave-django.jpg?ssl=1

Step-3: Creating a movie app

We will create a movie model with basic fields that a movie should have.

Before that, we should give some information about the field choices.

Why there is a URL field for poster rather than image field?

Because serving static files in production is not recommended, we use only the URL field. Fetching the image from remote and then saving it to our production storage is a topic of another post.

Because of this, we will save only the poster’s URL, not the poster’s itself as an image file. Also, sending static files like images is not a good approach.

We will send the exact URL of an image to the user. Then, the user’s browser fetches the image from this.

What is a slug and why it should be unique?

Let me explain with an example: I published  the original article on this blog. cbsofyalioglu[com]/post/django-and-modern-js-libraries-backend

The last part of the URL, django-and-modern-js-libraries-backend, is the slug of the post and also it is an identifier that makes the URL distinctive from other post pages.

In the GraphQL part of the tutorial, you will see that we will use this slug as a query parameter meaning that we will do database queries according to slug. Therefore, it should be unique.

We can also choose another identifier as the URL identifier, but it’s clear that the URL will not be a human-readable address.

Search engine indexing and ranking is a vital part of any website targeting new users. Readable URL addresses’ are good for users themselves and also suggested by search engine guides. Also, Google webmaster guidelines recommend using clean and concise URL structures.

Let’s make our model and define its properties and methods. In the next step, we will populate our database with initial records. Therefore, I added a class method responsible for the database population.

Let’s create a Django app. This app will include our model. The database tables will be done according to this. Also, API requests will be based on this.

<em># create new Django app</em> python manage.py startapp items
Code language: HTML, XML (xml)

Update settings .py

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', "django_extensions", 'graphene_django', 'corsheaders', "items" <em># New! (make our app will active)</em> ]
Code language: PHP (php)

Open ’djangoproject/items/models.py’ file and copy the below code.

<em># items.models</em> from django.db import models class Movie(models.Model): id = models.IntegerField(primary_key=True) name = models.CharField(max_length=100) year = models.IntegerField(null=True) summary = models.TextField(max_length=5000,null=True) poster_url = models.URLField(blank=True, null=True) slug = models.SlugField(max_length=50, null=True,blank =True, unique=True) <em># order items in descending order</em> class Meta: ordering = ["-year"] <em># the method which defines string output of class</em> def __str__(self): return self.name <em># the method which loads initial data</em> @classmethod def import_records(cls, record_list): for record in record_list: <em># create record if id is not exist</em> if not cls.objects.filter(id=record.get("id")).exists(): new_movie = cls.objects.create(**record) else: print(f"Id:{record.get('id')} is already exist.") print("Import operation done successfully")
Code language: HTML, XML (xml)
<em># make database migrations</em> python manage.py makemigrations python manage.py migrate
Code language: HTML, XML (xml)

Step-4: Populating database with initial data

There is no movie record currently in our database. We will provide a small initial data to create some movie records. All the data is provided by the community built The Movie Database. We will use those records in our app.

First, create an "initial_data.py" file in "djangoproject/utils" folder. After, you can copy and paste the below data to this new file.

initial_data = [{ 'id': 503919, 'name': 'The Lighthouse', 'year': 2019, 'summary': 'The hypnotic and hallucinatory tale of two lighthouse keepers on a remote and mysterious New England island in the 1890s.', 'slug': 'the-lighthouse-2019', 'poster_url': '<https://image.tmdb.org/t/p/w185/3nk9UoepYmv1G9oP18q6JJCeYwN.jpg>' },{ 'id': 475557, 'name': 'Joker', 'year': 2019, 'summary': 'During the 1980s, a failed stand-up comedian is driven insane and turns to a life of crime and chaos in Gotham City while becoming an infamous psychopathic crime figure.', 'slug': 'joker-2019', 'poster_url': '<https://image.tmdb.org/t/p/w185/udDclJoHjfjb8Ekgsd4FDteOkCU.jpg>' },{ 'id': 530385, 'name': 'Midsommar', 'year': 2019, 'summary': "A couple travels to Sweden to visit a rural hometown's fabled mid-summer festival. What begins as an idyllic retreat quickly devolves into an increasingly violent and bizarre competition at the hands of a pagan cult.", 'slug': 'midsommar-2019', 'poster_url': '<https://image.tmdb.org/t/p/w185/rXsh4MI6uyVgZBSSzXCfitJnVPy.jpg>' },{ 'id': 531428, 'name': 'Portrait of a Lady on Fire', 'year': 2019, 'summary': 'On an isolated island in Bretagne at the end of the eighteenth century, a female painter is obliged to paint a wedding portrait of a young woman.', 'slug': 'portrait-of-a-lady-on-fire-2019', 'poster_url': '<https://image.tmdb.org/t/p/w185/3NTEMlG5mQdIAlKDl3AJG0rX29Z.jpg>' }]
Code language: JavaScript (javascript)

Now, we will import and create new records at the database level. Normally we should have open Django shell. However, shell_plus command which is provided by django_extensions is more functional, so we will use this. It automatically imports all apps we created.

<em># open interactive shell</em> python manage.py shell_plus
Code language: HTML, XML (xml)
<em># let's check database and verify it's empty</em> Movie.objects.all() <em># prints: <QuerySet []></em> <em># import the records which we took it from github repo</em> from utils.initial_data import initial_data <em># create records in the database</em> Movie.import_records(initial_data) <em># prints 'Import operation done successfully'</em> <em># query database and verify it is not empty</em> Movie.objects.all()
Code language: HTML, XML (xml)

Our model and database are ready. You can close the shell with quit command.

The next section will be creating a GraphQL API.

Setting up GraphQL API

In this section, we will make our app’s API part with Graphene which is a GraphQL framework implementation of Python.

What we do in this section is:

Step 1 - Creating another Django app for API configurations

Actually, there is not any obligation to make another app because this app will not create or update any database table. However, to put all API-related configurations in one place, I chose this way.

Let’s create the second backend app. The name of the app should not have to be ‘gql’, but if you set another name, you should also change the name of the schema in settings .py later.

Open your terminal at the root level of your project.


https://i0.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/single-page-django-graphql.jpg?ssl=1
<em># create app with the name gql</em> python manage.py startapp gql <em># change directory</em> cd gql <em># create schema.py file</em> touch schema.py
Code language: HTML, XML (xml)

Step 2 - Creating an API Schema: API-model, Queries and Resolvers

API-schema will have three parts considering the scope of the article. Those are as follows:

A ) API-Model-Type and Resolvers

A class which is a mapped version of an existing Django model. It is the intermediary layer between the Django model (or database) and API response. The fields of ModelType will be the same fields of the corresponding model. We can also create custom fields that do not belong to the corresponding model.

You can check other scalar types from the Graphene Python documentation…

We will step by step write the schema .py file. You can copy and paste it.

https://i1.wp.com/cbsofyalioglucom.imfast.io/django-js-libraries/architecture-of-single-page-app.jpg?ssl=1

You can check other scalar types from the Graphene Python documentations…

We will step by step write the schema .py file. You can copy and paste it.

import graphene from items.models import Movie from graphene_django.types import DjangoObjectType <em># api-movie-model</em> class MovieType(DjangoObjectType): id = graphene.Int() name = graphene.String() year = graphene.Int() summary = graphene.String() poster_url = graphene.String() slug = graphene.String() <em># define which model will be the base</em> class Meta: model = Movie <em># 'self' corresponds to the item of Django model </em> <em># like The Lighthouse or Joker</em> def resolve_id(self, info): return self.id def resolve_name(self, info): return self.name def resolve_year(self, info): return self.year def resolve_summary(self, info): return self.summary def resolve_poster_url(self, info): return self.poster_url def resolve_slug(self, info): return self.slug
Code language: HTML, XML (xml)

Let me explain the above code.

The 'MovieType’ class is a mapped version of Movie model. You may notice that all the fields are the same. We defined the base model in class Meta, so the movie model will be the base model.

It is important to say that resolver names are written in snake case like ‘resolve_poster_url’. However, when we write client-side queries, those will be pascal case such as ‘posterUrl’. You see that later.

B ) Queries and Resolvers

The client-side app will use these queries for distinct requests. We will also write client-side queries on its part. A client-side query should match with the server-side query. Therefore, this part also defines the allowable requests of the frontend part.

For the sake of simplicity, we will define only two queries.

Let add this code below MovieType class.

class Query(graphene.ObjectType): movie_list = graphene.List(MovieType) movie = graphene.Field(MovieType, slug=graphene.String()) def resolve_movie_list(self, info, *_): <em># for large lists only query what you need</em> return Movie.objects.all().only("name", "poster_url", "slug") def resolve_movie(self, info, slug): movie_queryset = Movie.objects.filter(slug=slug) if movie_queryset.exists(): return movie_queryset.first() schema = graphene.Schema(query=Query)
Code language: HTML, XML (xml)

In the last row, you will see a schema object. This is the root node of the API. We should tell the Django server to use this as our API schema. To do so, update the settings. py.

<em># djangoproject/djangoproject/settings.py</em> <em># New - Add this part</em> GRAPHENE= {'SCHEMA': 'gql.schema.schema'} <em># MIDDLEWARE = [..]</em>
Code language: HTML, XML (xml)

Step 3 - Create URL endpoints

In REST API, we define different URL Endpoints for different requests. One of the good part of GraphQL is that we will only define one endpoint. All the requests will be done through that.

Copy the below code and paste it to djangoproject/djangoproject/urls .py file.

from django.contrib import admin from django.urls import path from graphene_django.views import GraphQLView from django.views.decorators.csrf import csrf_exempt from django.views.generic import TemplateView urlpatterns = [ path('admin/', admin.site.urls), <em># apiclient on client-side will request this adress later</em> path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True))), <em># index.html file will be our root template. When a user opens our webste,</em> <em># this file will be sent by server at first. After then, api requests</em> <em># will directed above address.</em> <em># (it points to ~/Blog/djr/templates/index.html)</em> <em># (currently there is no file, webpack production bundle will come here )</em> path("", TemplateView.as_view(template_name="index.html")), ]
Code language: PHP (php)

You noticed that we set graphiql=True. This is GraphQL interactive panel. We can make a query like a client app through this panel. You will also see the details of all queries.

Now, please run the server in the root folder : ‘djangoproject/’

python [manage.py](<http://manage.py/>) runserver
Code language: HTML, XML (xml)

Open 127.0.0.1:8000/graphql address from your browser. We will query the movie with specific identifier (slug). On the left panel, paste this and press the Execute Query button.

Please note that, we request fields with pascalCase. (posterUrl)

query { movie(slug:"the-lighthouse-2019"){ id, name, posterUrl } }
Code language: JavaScript (javascript)

and the response will be in JSON format like this:

{ "data": { "movie": { "id": 503919, "name": "The Lighthouse", "posterUrl": "<https://image.tmdb.org/t/p/w185/3nk9UoepYmv1G9oP18q6JJCeYwN.jpg>" } } }
Code language: JSON / JSON with Comments (json)

Our API is ready to respond to the requests. This part of the tutorial is finished.

Now, we will make two different client-side apps. Please choose one of them to continue.

Option One: Make front-end part with React

Option Two: Make front-end part with Svelte