Django Projects
Create an Inventory Management System With Python and Django in Bangla Part-2: Create Django Template
Build an Inventory Management System With Python and Django in Bangla Series এর দ্বিতীয় পর্বে আপনাকে স্বাগতম। এই পর্বে আমাদের ইনভেন্টরি এর জন্য প্রস্তুত কৃত HTML Template কে Django Templates এ convert করা যায় তা আমি আপনাদেরকে দেখাবো।
Django Inventory Backend UI
প্রথমে এই লিংকে গিয়ে দেখে নিতে পারেন , আমাদের Python and Django দিয়ে তৈরি Inventory এর Backend UI কেমন হবে। এবং এখান থেকে ডাউনলোড করে নিতে পারেন।
Django Template Conversion
HTML Template কে Django Template এ রূপান্তর করার জন্য আমরা প্রথমে মূল প্রজেক্ট directory এর মধ্যে প্রথমে templates, static এবং assets নামে তিনটি ফোল্ডার তৈরি করব। তারপর template file গুলোকে আবার দুইভাবে রাখার জন্য আমরা dashboard এবং partials নামে দুটি ফোল্ডার করব। এর মধ্যে partials ফোল্ডারের মধ্যে আমরা মূলতঃ যে সব টেম্পলেট file গুলো রিপিটেড ব্যবহার হবে , সেগুলোকে রাখব। আর মূল পেজ গুলো আমরা dashboard ফোল্ডারের মধ্যে রাখব। এছাড়া static ফোল্ডারে আমাদের static ফাইল গুলো যেমন css, js ফাইল গুলো থাকবে। আর assets ফোল্ডারের মধ্যে compiled css,js,images গুলো থাকবে।
প্রথমে আপনার Base Directory এর মধ্যে templates, static এবং assets নামে তিনটি ফোল্ডার করে ফেলুন। নিচের ছবির সাথে মিলিয়ে নিন :
এবার আপনার custom css file কে সদ্য তৈরী করা static ফোল্ডারের মধ্যে css ফোল্ডারে রাখুন :
এইবার উক্ত template directory কে inventory directory এর মধ্যে অবস্থিত settings.py ফাইলের ৫৮ নম্বর লাইনে রেজিস্ট্রি করে দিয়ে আসুন। ঠিক এইরকম:
এবং static File গুলোকেও নিচের মতো করে settings.py ফাইলে static file সেক্শনে রেজিস্ট্রেশন করে রাখুন :
এইবার আপনার templates directory এর মধ্যে dashboard এবং partials নামে দুটি Folder তৈরি করুন :
এইবার আপনার partials directory এর মধ্যে nav.html নামে নিম্নোক্ত কোডগুলো দিয়ে একটি html file তৈরি করুন :
templates/partials/nav.html
<!--Navbar--> <nav class="navbar navbar-expand-lg navbar-info bg-info"> <div class="container"> <a class="navbar-brand text-white" href="{% url 'index' %}">Django Inventory</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link text-white" href="{% url 'index' %}">Dashboard <span class="sr-only">(current)</span></a> </li> </ul> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a class="nav-link text-white" href="profile.html">Admin Profile <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link text-white" href="#">Logout</a> </li> </ul> </div> </div> </nav> <!--End Navbar-->
এইবার আপনার partials directory এর মধ্যে topside.html নামে নিম্নোক্ত কোডগুলো দিয়ে একটি html file তৈরি করুন :
templates/partials/topside.html
<!--Topside--> <div class="container"> <div class="row mt-4"> <div class="col-md-4"> <div class="card"> <div class="card-header bg-info text-white"> Information </div> <div class="card-body"> <marquee behavior="" direction=""> <h3 class="my-4">This is the Information</h3> </marquee> </div> </div> </div> <div class="col-md-8"> <div class="card"> <div class="card-header bg-info text-white"> Statistics </div> <div class="card-body"> <div class="row"> <div class="col-md-4"> <a class="text-decoration-none text-dark" href="{% url 'staff' %}"> <div class="card my-card shadow text-center p-3"> <h4>Staff <i class="fas fa-users"></i></h4> <h3>4</h3> </div> </a> </div> <div class="col-md-4"> <a class="text-decoration-none text-dark" href="{% url 'products' %}"> <div class="card my-card shadow text-center p-3"> <h4>Products <i class="fas fa-box"></i></h4> <h3>4</h3> </div> </a> </div> <div class="col-md-4"> <a class="text-decoration-none text-dark" href="{% url 'orders' %}"> <div class="card my-card shadow text-center p-3"> <h4>Orders <i class="fas fa-shipping-fast"></i></h4> <h3>4</h3> </div> </a> </div> </div> </div> </div> </div> </div> </div> <!--End Topside-->
এইবার আপনার partials directory এর মধ্যে graphs.html নামে নিম্নোক্ত কোডগুলো দিয়ে একটি html file তৈরি করুন :
templates/partials/graphs.html
<div class="container"> <div class="row my-5"> <div class="col-md-6"> <div class="bg-white"> <canvas id="myChart1" width="400" height="300"></canvas> <script> var ctx = document.getElementById('myChart1').getContext('2d'); var myChart1 = new Chart(ctx, { type: 'pie', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: 'Products', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: true } }] } } }); </script> </div> </div> <div class="col-md-6"> <div class="bg-white"> <canvas id="myChart" width="400" height="300"></canvas> <script> var ctx = document.getElementById('myChart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: 'Products', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: true } }] } } }); </script> </div> </div> </div> </div>
এইবার আপনার partials directory এর মধ্যে base.html নামে নিম্নোক্ত কোডগুলো দিয়ে একটি html file তৈরি করুন, এবং nav.html ফাইলকে include করে দিন এবং title এবং content block কে যুক্ত করে দিন:
templates/partials/base.html
{% load static %} <!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous"> <!--FontAwesome CDN--> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.2/css/all.css" integrity="sha384-vSIIfh2YWi9wW0r9iZe7RJPrKwp6bG+s9QZMoITbCckVJqGCCRhc+ccxNcdpHuYu" crossorigin="anonymous"> <!--Chartjs CDN--> <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js"></script> <!--Custome CSS--> <link rel="stylesheet" href="{% static 'css/style.css' %}"> <title>{% block title %} {% endblock %}</title> </head> <body> {% include 'partials/nav.html' %} <div class="container"> {% block content %} {% endblock %} </div> <!-- Optional JavaScript; choose one of the two! --> <!-- Option 1: jQuery and Bootstrap Bundle (includes Popper) --> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script> <!-- Option 2: Separate Popper and Bootstrap JS --> <!-- <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous"></script> --> </body> </html>
ব্যাখ্যা:
- প্রথম লাইনে static file গুলো লোড করার ব্যবস্থা করেছি।
- কোডের ২৩ নম্বর লাইনে আমরা <title><title/> কে ডাইনামিক এর কাজ করেছি। অর্থাৎ বিভিন্ন পেজ গুলো লোড হওয়ার সাথে যেন তাদের title দেখায় , সে জন্য আমরা title block যুক্ত করেছি।
- ২৭ নম্বর লাইনে nav.html ফাইলকে include করে নিয়েছি।
- উপরের কোডের ২৯ নম্বর লাইনে আমরা content কে ডাইনামিক এর কাজ করেছি। অর্থাৎ বিভিন্ন পেজ গুলো লোড হওয়ার সাথে যেন তাদের content দেখায় , সে জন্য আমরা content block যুক্ত করেছি।
Create Main Pages
এইবার আমরা dashboard এর সব গুলো পেজ কে তৈরি করে ফেলব।প্রথমে Home Page নিয়ে কাজ করব। এর জন্য আপনি আপনার dashboard directory এর মধ্যে index.html নামে নিম্নোক্ত কোডগুলো দিয়ে একটি html file তৈরি করুন :
templates/dashboard/index.html
{% extends 'partials/base.html' %} {% block title %}Dashboard Home Page {% endblock %} {% block content %} {% include 'partials/topside.html' %} {% include 'partials/graphs.html' %} {% endblock %}
একইভাবে আপনার dashboard directory এর মধ্যে staff.html,products.html,orders.html নামে html file গুলো নিম্নোক্ত কোডগুলো দিয়ে তৈরি করে রাখতে পারেন :
templates/dashboard/staff.html
{% extends 'partials/base.html' %} {% block title %}Staff Page {% endblock %} {% block content %} {% include 'partials/topside.html' %} <div class="row my-4"> <div class="col-md-4"></div> <div class="col-md-8"> <table class="table bg-white"> <thead class="bg-info"> <tr class="text-white"> <th scope="col">#</th> <th scope="col">First</th> <th scope="col">Last</th> <th scope="col">Handle</th> </tr> </thead> <tbody> <tr> <th scope="row"><a class="btn btn-info btn-sm" href="">View</a></th> <td>Mark</td> <td>Otto</td> <td>@mdo</td> </tr> <tr> <th scope="row"><a class="btn btn-info btn-sm" href="">View</a></th> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> </tr> <tr> <th scope="row"><a class="btn btn-info btn-sm" href="">View</a></th> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> </tr> </tbody> </table> </div> </div> {% endblock %}
templates/dashboard/products.html
{% extends 'partials/base.html' %} {% block title %}Products Page {% endblock %} {% block content %} {% include 'partials/topside.html' %} <div class="row my-4"> <div class="col-md-4"> <div class="border bg-white p-3"> <h4>Add Products</h4> <hr> <form action=""> <div class="form-group"> <label for="exampleInputEmail1">Name</label> <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"> </div> <div class="form-group"> <label for="exampleInputPassword1">Quantity</label> <input type="password" class="form-control" id="exampleInputPassword1"> </div> <div class="form-group "> <label for="inputState">Category</label> <select id="inputState" class="form-control"> <option selected>Choose...</option> <option>...</option> </select> </div> <input class="btn btn-success btn-block" type="submit" value="Add Product"> </form> </div> </div> <div class="col-md-8"> <table class="table bg-white"> <thead class="bg-info"> <tr class="text-white"> <th scope="col">#</th> <th scope="col">Name</th> <th scope="col">Category</th> <th scope="col">Quantity</th> <th scope="col">Activity</th> </tr> </thead> <tbody> <tr> <th scope="row">1</th> <td>Mark</td> <td>Otto</td> <td>@mdo</td> <td> <a class="btn btn-info btn-sm" href="">Edit</a> <a class="btn btn-danger btn-sm" href="">Delete</a> </td> </tr> <tr> <th scope="row">2</th> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> <td> <a class="btn btn-info btn-sm" href="">Edit</a> <a class="btn btn-danger btn-sm" href="">Delete</a> </td> </tr> <tr> <th scope="row">3</th> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> <td> <a class="btn btn-info btn-sm" href="">Edit</a> <a class="btn btn-danger btn-sm" href="">Delete</a> </td> </tr> </tbody> </table> </div> </div> {% endblock %}
templates/dashboard/orders.html
{% extends 'partials/base.html' %} {% block title %}Orders Page {% endblock %} {% block content %} {% include 'partials/topside.html' %} <div class="row my-4"> <div class="col-md-4"> </div> <div class="col-md-8"> <table class="table bg-white"> <thead class="bg-info"> <tr class="text-white"> <th scope="col">#</th> <th scope="col">Product</th> <th scope="col">Category</th> <th scope="col">Quantity</th> <th scope="col">Order by</th> </tr> </thead> <tbody> <tr> <th scope="row">1</th> <td>Mark</td> <td>Otto</td> <td>@mdo</td> <td> Broni </td> </tr> <tr> <th scope="row">2</th> <td>Jacob</td> <td>Thornton</td> <td>@fat</td> <td> Kenneth </td> </tr> <tr> <th scope="row">3</th> <td>Larry</td> <td>the Bird</td> <td>@twitter</td> <td> Cecilia </td> </tr> </tbody> </table> </div> </div> {% endblock %}
ব্যাখ্যা: উপরের সবগুলো পেজকেই আমি base.html থেকে extend করেছি। এবং প্রত্যেকটি পেজের title block এর মধ্যে আলাদা টাইটেল যুক্ত করেছি। যেন পেজ গুলো লোড হওয়ার সাথে তাদের টাইটেল ও স্বতন্ত্র হয়।
এবার আপনার dashboard ফোল্ডারের মধ্যে অবস্থিত views.py ফাইলে প্রতিটি পেজের জন্য নিচের মতো করে একটি ফাঙ্কশন ডিফাইন করে দিন:
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def index(request): return render(request,'dashboard/index.html') def staff(request): return render(request,'dashboard/staff.html') def products(request): return render(request,'dashboard/products.html') def orders(request): return render(request,'dashboard/orders.html')
এবার dashboard apps ফোল্ডারের এর মধ্যে urls.py ফাইলে নিচের মতো করে প্রতিটি URL ডিফাইন করে দিন :
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('staff/', views.staff, name='staff'), path('products/', views.products, name='products'), path('orders/', views.orders, name='orders'), ]
Finally আপনার প্রজেক্ট ফোল্ডারে নিম্নোক্ত কম্যান্ড রানের মাধ্যমে সবগুলো স্ট্যাটিক ফাইল কে কম্পাইল করে নিন :
python manage.py collectstatic
এখন যদি আপনি http://localhost:8000/ ভিজিট করেন, তাহলে নিম্নোক্ত রেজাল্ট পাবেনঃ