djangogpt astra

 

আমি windows 10 use করি।এখন আমি আমার desktop এ djnagosite নামে একটা ফোল্ডার এ তোমার ইচ্ছামত নাম দিয়ে একটা ৩ পেইজের ওয়েবসাইট বানিয়ে দাও। আমি windows powershell and vs code editor ইউজ করতে চাই। একেবারে শূন্য থেকে খুব ভালো করে সহজ করে শিখিয়ে দাও কোডের ব্যাখ্যা সহ ।আমার লক্ষ্য django দিয়ে যেকোনো এডুকেশন ওয়েবসাইট এবং ই কমার্স যেন বানাতে পারি,এখন শুরু করো। কোন ভুল করবে না। একেবারে সঠিক তথ্য ও কোড দিবে যেন ভবিষ্যতে vps এ সাইট বানাতে পারি djnago দিয়ে

•

12:40 AM

GPT 6 Astra

GPT 6 Astra

আমরা Django দিয়ে “EduShop” নামে একটি ৩ পেজের ওয়েবসাইট বানাব। এটি হবে তোমার ভবিষ্যতের এডুকেশন ওয়েবসাইট ও ই-কমার্স শেখার ভিত্তি।


আমি তোমার কম্পিউটারে সরাসরি ফাইল তৈরি করতে পারছি না; তবে কোন কমান্ড কোথায় চালাবে, কোন ফাইলে কী লিখবে এবং কোড কীভাবে কাজ করে—সব ধাপে ধাপে দেখাচ্ছি।


একটি বাস্তব কথা: কোড সঠিক হলেও Python-এর ইনস্টলেশন, ফোল্ডারের অবস্থান বা PowerShell-এর সেটিংসের কারণে সমস্যা হতে পারে। কোনো ধাপে error হলে পরের ধাপে না গিয়ে সেই error-এর সম্পূর্ণ লেখা পাঠাবে।


১. কী বানাব?

আমাদের সাইটে সাধারণ দর্শকদের জন্য তিনটি পেজ থাকবে:


পেজ ঠিকানা কাজ

হোম / ওয়েবসাইটের পরিচিতি

কোর্স /courses/ ডেটাবেস থেকে কোর্স দেখানো

যোগাযোগ /contact/ ফর্মের তথ্য ডেটাবেসে সংরক্ষণ

এগুলোর বাইরে Django-এর তৈরি Admin Panel থাকবে:


text


Copy



/admin/

সেখান থেকে তুমি:


নতুন কোর্স যোগ করতে পারবে।

কোর্সের দাম পরিবর্তন করতে পারবে।

কোর্স প্রকাশ বা লুকিয়ে রাখতে পারবে।

যোগাযোগ ফর্মে আসা মেসেজ দেখতে পারবে।

আমরা ব্যবহার করব:


Python 3.13

Django 5.2 LTS

HTML ও CSS

SQLite ডেটাবেস

Windows PowerShell

VS Code

Django 5.2 LTS বেছে নিচ্ছি কারণ এটি দীর্ঘমেয়াদি সাপোর্টের সংস্করণ। প্রথম প্রজেক্টে SQLite সহজ; পরে VPS-এ PostgreSQL ব্যবহার শিখব।


২. Django কীভাবে কাজ করে?

সহজ করে পুরো পথটি দেখো:


text


Copy



ব্রাউজারে ঠিকানা লেখা

        ↓

urls.py ঠিক করে কোন view চলবে

        ↓

views.py প্রয়োজনীয় কাজ করে

        ↓

প্রয়োজনে Model দিয়ে ডেটাবেস থেকে তথ্য আনে

        ↓

Template দিয়ে HTML তৈরি করে

        ↓

ব্রাউজারে পেজ দেখায়

মূল ধারণা:


বিষয় অর্থ

Project পুরো ওয়েবসাইটের সেটিংস ও মূল কাঠামো

App ওয়েবসাইটের একটি কাজের অংশ

Model ডেটাবেসে কী ধরনের তথ্য থাকবে তার Python সংজ্ঞা

View একটি request পেলে কী কাজ হবে

Template ব্রাউজারে দেখানোর HTML

URL কোন ঠিকানা কোন view চালাবে

Form ব্যবহারকারীর তথ্য গ্রহণ ও যাচাই করার ব্যবস্থা

আমাদের project-এর নাম হবে config, আর app-এর নাম হবে core।


config শুধু ভেতরের Python package-এর নাম। ওয়েবসাইটের নাম EduShop।


৩. Python ও VS Code প্রস্তুত করো

৩.১ Python ইনস্টল

অফিশিয়াল ওয়েবসাইট থেকে Python 3.13-এর Windows installer ইনস্টল করো:


https://www.python.org/downloads/windows/


ইনস্টল করার সময় সুযোগ থাকলে:


text


Copy



Add python.exe to PATH

অপশনটি নির্বাচন করো। Python Launcher-ও ইনস্টল রাখো।


ইনস্টল শেষে নতুন PowerShell খুলে চালাও:


powershell


Copy



py -3.13 --version

এ ধরনের ফলাফল আসবে:


text


Copy



Python 3.13.x

এখানে x-এর জায়গায় তোমার ইনস্টল করা patch version থাকবে।


ইনস্টল করা Python-এর তালিকা দেখতে:


powershell


Copy



py -0p

py command পাওয়া না গেলে Python installation/Launcher ঠিক করতে হবে। এই পরীক্ষা সফল হওয়ার পরেই এগোও।


৩.২ VS Code ইনস্টল

অফিশিয়াল লিংক:


https://code.visualstudio.com/


VS Code-এর Extensions থেকে ইনস্টল করো:


text


Copy



Python

Publisher: Microsoft

৪. Desktop-এ djnagosite ফোল্ডার তৈরি

তুমি ফোল্ডারের নাম djnagosite বলেছ, তাই সেই বানানই রাখছি।


PowerShell-এ নিচের কমান্ডগুলো চালাও:


powershell


Copy



$desktop = [Environment]::GetFolderPath("Desktop")

$projectPath = Join-Path $desktop "djnagosite"


New-Item -ItemType Directory -Path $projectPath -Force | Out-Null

Set-Location $projectPath

এভাবে Desktop যদি OneDrive-এর ভেতরেও থাকে, Windows-এর নির্ধারিত Desktop path ব্যবহার হবে।


তুমি কোথায় আছ দেখতে:


powershell


Copy



Get-Location

ফলাফলের শেষে থাকা উচিত:


text


Copy



Desktop\djnagosite

ফোল্ডারটিতে আগে থেকে কোনো Django project থাকলে সেটির ওপর এই tutorial-এর ফাইল লিখবে না। আগে backup রাখবে।


৫. Virtual environment তৈরি

একেক প্রজেক্টের Python package আলাদা রাখার জন্য virtual environment ব্যবহার করা হয়।


চালাও:


powershell


Copy



py -3.13 -m venv .venv

তারপর activate করো:


powershell


Copy



.\.venv\Scripts\Activate.ps1

সফল হলে PowerShell prompt-এর শুরুতে সাধারণত দেখাবে:


text


Copy



(.venv)

যদি script execution error আসে

শুধু বর্তমান PowerShell session-এর জন্য চালাও:


powershell


Copy



Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned

তারপর আবার:


powershell


Copy



.\.venv\Scripts\Activate.ps1

এটি চালাতে সাধারণত Administrator হিসেবে PowerShell খোলার প্রয়োজন নেই। কোনো অফিসের managed computer হলে প্রতিষ্ঠানের policy এটি আটকাতে পারে।


সঠিক Python ব্যবহার হচ্ছে কি না দেখো:


powershell


Copy



python -c "import sys; print(sys.executable)"

ফলাফলের শেষে থাকবে:


text


Copy



djnagosite\.venv\Scripts\python.exe

Virtual environment activate করতে না পারলেও নির্দিষ্ট Python সরাসরি চালানো যায়: .\.venv\Scripts\python.exe। তবে পরের নির্দেশনাগুলোতে ধরে নিচ্ছি environment activate করা আছে।


৬. Django ইনস্টল

চাল


You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:41 AM

m

You

Continue





•

12:42 AM

GPT 6 Astra

GPT 6 Astra

আগের ধাপে আমরা Desktop-এর djnagosite ফোল্ডারে virtual environment তৈরি ও activate করেছি। এবার Django ইনস্টল করে পুরো ওয়েবসাইট বানাব।


এখন থেকে সব PowerShell কমান্ড djnagosite ফোল্ডারে চালাবে।


Terminal-এর শুরুতে (.venv) থাকা উচিত। কোডের মধ্যে দেওয়া >>> বা prompt কপি করার প্রয়োজন নেই—আমি কমান্ডগুলো আলাদা করে দিচ্ছি।


৬. Django ইনস্টল করো

PowerShell-এ চালাও:


powershell


Copy



python -m pip install --upgrade pip

python -m pip install "Django>=5.2,<5.3"

এতে Django 5.2 সিরিজের সর্বশেষ উপলব্ধ patch release ইনস্টল হবে; 5.3 বা 6.0 ইনস্টল হবে না।


ইনস্টল ঠিক হয়েছে কি না দেখো:


powershell


Copy



python -m django --version

ফলাফল হবে:


text


Copy



5.2.x

এখানে x তোমার ইনস্টল হওয়া patch version।


কমান্ডের ব্যাখ্যা

python -m pip: বর্তমানে নির্বাচিত Python-এর package installer চালায়।

install: package ইনস্টল করে।

Django>=5.2,<5.3: কোন version range চাই তা নির্ধারণ করে।

৭. Project ও app তৈরি করো

প্রথমে Django project:


powershell


Copy



python -m django startproject config .

শেষের . খুব গুরুত্বপূর্ণ। এর অর্থ: বর্তমান djnagosite ফোল্ডারের মধ্যেই project তৈরি করো।


এখন app তৈরি করো:


powershell


Copy



python manage.py startapp core

বর্তমানে কাঠামো হবে:


text


Copy



djnagosite/

├── .venv/

├── config/

│   ├── __init__.py

│   ├── asgi.py

│   ├── settings.py

│   ├── urls.py

│   └── wsgi.py

├── core/

│   ├── migrations/

│   ├── __init__.py

│   ├── admin.py

│   ├── apps.py

│   ├── models.py

│   ├── tests.py

│   └── views.py

└── manage.py

গুরুত্বপূর্ণ ফাইল

ফাইল কাজ

manage.py Django-এর বিভিন্ন command চালায়

config/settings.py পুরো project-এর configuration

config/urls.py মূল URL তালিকা

core/models.py ডেটাবেসের কাঠামো

core/views.py পেজের logic

core/admin.py Admin Panel-এর configuration

.venv-এর ভেতরে তোমার ওয়েবসাইটের কোনো কোড লিখবে না।


৮. VS Code-এ project খোলো

PowerShell-এ:


powershell


Copy



code .

যদি code command পাওয়া না যায়:


VS Code খোলো।

File → Open Folder নির্বাচন করো।

Desktop-এর djnagosite ফোল্ডার খোলো।

Python interpreter নির্বাচন

VS Code-এ:


Ctrl + Shift + P চাপো।

লিখো: Python: Select Interpreter

.venv-এর interpreter নির্বাচন করো।

যদি তালিকায় না থাকে, Enter interpreter path থেকে নির্বাচন করো:


text


Copy



djnagosite\.venv\Scripts\python.exe

VS Code-এর PowerShell terminal

Terminal → New Terminal দিয়ে terminal খোলো।


Terminal PowerShell না হলে terminal-এর পাশের dropdown থেকে PowerShell নির্বাচন করো।


নতুন terminal-এ প্রয়োজন হলে activate করো:


powershell


Copy



.\.venv\Scripts\Activate.ps1

এবং যাচাই করো:


powershell


Copy



Get-Location

বর্তমান ফোল্ডার হতে হবে djnagosite।


৯. Templates ও CSS-এর ফোল্ডার তৈরি

PowerShell-এ চালাও:


powershell


Copy



New-Item -ItemType Directory -Force -Path "templates\core", "static\css" | Out-Null

এবার VS Code Explorer থেকে নিচের নতুন ফাইলগুলো তৈরি করো:


text


Copy



core/urls.py

core/forms.py


templates/base.html

templates/core/home.html

templates/core/courses.html

templates/core/contact.html


static/css/style.css

VS Code-এ কোনো folder-এর ওপর right-click করে New File নির্বাচন করলে ফাইল তৈরি করা যায়।


১০. Django settings ঠিক করো

খোলো:


text


Copy



config/settings.py

এই ফাইলে কিছু অংশ পরিবর্তন করব। পুরো ফাইল মুছে ফেলবে না।


১০.১ App register করো

INSTALLED_APPS খুঁজে এটিকে এমন করো:


python


Copy



INSTALLED_APPS = [

    "django.contrib.admin",

    "django.contrib.auth",

    "django.contrib.contenttypes",

    "django.contrib.sessions",

    "django.contrib.messages",

    "django.contrib.staticfiles",

    "core.apps.CoreConfig",

]

শেষের লাইনটি Django-কে আমাদের core app সম্পর্কে জানায়।


১০.২ Templates folder নির্ধারণ করো

TEMPLATES অংশ খুঁজে শুধু DIRS লাইনটি বদলাও:


python


Copy



"DIRS": [BASE_DIR / "templates"],

পরিবর্তনের পর পুরো অংশটি হবে:


python


Copy



TEMPLATES = [

    {

        "BACKEND": "django.template.backends.django.DjangoTemplates",

        "DIRS": [BASE_DIR / "templates"],

        "APP_DIRS": True,

        "OPTIONS": {

            "context_processors": [

                "django.template.context_processors.request",

                "django.contrib.auth.context_processors.auth",

                "django.contrib.messages.context_processors.messages",

            ],

        },

    },

]

ব্যাখ্যা:


BASE_DIR: project-এর মূল ফোল্ডার।

BASE_DIR / "templates": সেই ফোল্ডারের templates directory।

APP_DIRS=True: app-এর ভেতরের template directory-ও খোঁজে।

১০.৩ ভাষা ও সময়

বিদ্যমান


You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:43 AM

m

You

Continue





•

12:43 AM

GPT 6 Astra

GPT 6 Astra

আমরা config/settings.py ফাইলের সেটিংস ঠিক করছিলাম। সেখান থেকেই শুরু করি।


আজকের বাকি ধাপগুলো শেষ করলে তোমার সাইটে থাকবে:


সুন্দর হোম পেজ।

ডেটাবেস থেকে দেখানো কোর্সের তালিকা।

কার্যকর যোগাযোগ ফর্ম।

কোর্স ও মেসেজ পরিচালনার Admin Panel।

মনে রাখবে: সব command চালাবে djnagosite ফোল্ডারে, যেখানে manage.py আছে। আর প্রতিটি ফাইলের কোড লেখার পরে Ctrl + S দিয়ে save করবে।


১০.৩ ভাষা ও সময় নির্ধারণ

config/settings.py ফাইলে বিদ্যমান LANGUAGE_CODE, TIME_ZONE, USE_I18N এবং USE_TZ লাইনগুলো খুঁজে এমন করো:


python


Copy



LANGUAGE_CODE = "bn"


TIME_ZONE = "Asia/Dhaka"


USE_I18N = True


USE_TZ = True

ব্যাখ্যা

bn: Django-এর যেসব built-in লেখা বাংলায় অনূদিত আছে, সেগুলো বাংলায় দেখাবে।

Asia/Dhaka: বাংলাদেশের সময় অঞ্চল।

USE_I18N: অনুবাদ ব্যবস্থা চালু রাখে।

USE_TZ: timezone-aware তারিখ ও সময় ব্যবহার করে।

তুমি বাংলাদেশের বাইরে হলে প্রয়োজন অনুযায়ী timezone বদলাতে পারবে।


১০.৪ CSS-এর settings

একই ফাইলে STATIC_URL লাইনটি খুঁজে নিচের মতো করো। এরপর তার নিচে STATICFILES_DIRS যোগ করো:


python


Copy



STATIC_URL = "static/"


STATICFILES_DIRS = [

    BASE_DIR / "static",

]

এতে Django আমাদের তৈরি static ফোল্ডার থেকে CSS খুঁজে পাবে।


১০.৫ স্থানীয়ভাবে ব্যবহারের host

ALLOWED_HOSTS খুঁজে পরিবর্তন করো:


python


Copy



ALLOWED_HOSTS = ["127.0.0.1", "localhost"]

এখন শেখার সময় এটি থাকবে:


python


Copy



DEBUG = True

VPS-এ live করার সময় DEBUG = False করতে হবে। আরও deployment settings লাগবে—শেষে সেটি বলছি।


১০.৬ Database এখন পরিবর্তন করতে হবে না

Django তৈরি করে দেওয়া এই configuration রাখো:


python


Copy



DATABASES = {

    "default": {

        "ENGINE": "django.db.backends.sqlite3",

        "NAME": BASE_DIR / "db.sqlite3",

    }

}

SQLite একটি ফাইলে তথ্য সংরক্ষণ করে। প্রথম project শেখার জন্য আলাদা database server ইনস্টল করতে হচ্ছে না।


১১. Model: ডেটাবেসের কাঠামো তৈরি

আমাদের দুটি ধরনের তথ্য রাখতে হবে:


কোর্স।

যোগাযোগের মেসেজ।

খোলো:


text


Copy



core/models.py

ফাইলের বর্তমান কোড বদলে নিচের কোড দাও:


python


Copy



from decimal import Decimal


from django.core.validators import MinValueValidator

from django.db import models



class Course(models.Model):

    title = models.CharField("কোর্সের নাম", max_length=200)

    description = models.TextField("বিবরণ")

    price = models.DecimalField(

        "মূল্য",

        max_digits=10,

        decimal_places=2,

        validators=[MinValueValidator(Decimal("0.00"))],

    )

    is_published = models.BooleanField("প্রকাশিত", default=True)

    created_at = models.DateTimeField("তৈরির সময়", auto_now_add=True)


    class Meta:

        ordering = ["-created_at", "-pk"]

        verbose_name = "কোর্স"

        verbose_name_plural = "কোর্সসমূহ"


    def __str__(self):

        return self.title



class ContactMessage(models.Model):

    name = models.CharField("নাম", max_length=100)

    email = models.EmailField("ইমেইল")

    message = models.TextField("মেসেজ", max_length=2000)

    created_at = models.DateTimeField("পাঠানোর সময়", auto_now_add=True)


    class Meta:

        ordering = ["-created_at", "-pk"]

        verbose_name = "যোগাযোগের মেসেজ"

        verbose_name_plural = "যোগাযোগের মেসেজসমূহ"


    def __str__(self):

        return f"{self.name} - {self.email}"

কোডের ব্যাখ্যা

class Course(models.Model)

Django-কে বলছি: Course একটি database model।


Migration চালানোর পরে এর জন্য database table তৈরি হবে।


Field-এর ধরন

Field কাজ

CharField ছোট লেখা

TextField বড় লেখা

EmailField ইমেইল সংরক্ষণ; form validation-এ ইমেইলের গঠন যাচাই

DecimalField নির্দিষ্ট দশমিক ঘরসহ সংখ্যা

BooleanField সত্য/মিথ্যা

DateTimeField তারিখ ও সময়

টাকার জন্য DecimalField কেন?

টাকার হিসাবের জন্য সাধারণত FloatField নয়, DecimalField ব্যবহার করা উচিত। এতে binary floating-point rounding-এর সমস্যা এড়ানো যায়।


python


Copy



max_digits=10

decimal_places=2

মানে সর্বোচ্চ ১০টি digit, যার মধ্যে দশমিকের পরে ২টি।


python


Copy



MinValueValidator(Decimal("0.00"))

Admin বা Django form দিয়ে তথ্য যাচাই করার সময় ঋণাত্মক দাম গ্রহণ করবে না।


Model-এর save() সরাসরি চালালে সব validator স্বয়ংক্রিয়ভাবে চলে না। পরবর্তী সময়ে API বা অন্য write path তৈরি করলে validation এবং প্রয়োজনমতো database constraint-ও যোগ করতে হবে।


auto_now_add=True

রেকর্ড প্রথম তৈরি হওয়ার সময় Django নিজে সময় বসাবে।


ordering

python


Copy



ordering = ["-created_at", "-pk"]

নতুন রেকর্ড আগে দেখাবে। pk হলো primary key—সাধারণত Django-এর তৈরি unique ID।


__str__

Admin-এ কোর্সকে শুধু Course object (1) না দেখিয়ে কোর্সের নাম দেখায়।


১২.

You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:43 AM

m

You

Continue





•

12:44 AM

GPT 6 Astra

GPT 6 Astra

এবার আমরা Admin Panel, যোগাযোগ ফর্ম, তিনটি পেজ এবং ডিজাইন তৈরি করে সাইট চালু করব।


কাজের নিয়ম: নিচে কোনো ফাইলের সম্পূর্ণ কোড দিলে, সেই ফাইলের আগের কোড সরিয়ে নতুন কোড বসাবে। config/settings.py-এর ক্ষেত্রে আগের ধাপে করা পরিবর্তনগুলো রেখো।


১২. Admin Panel প্রস্তুত করো

Django-এর built-in Admin Panel থেকে কোর্স যোগ করা এবং যোগাযোগের মেসেজ দেখা যাবে।


খোলো:


text


Copy



core/admin.py

কোড দাও:


python


Copy



from django.contrib import admin


from .models import ContactMessage, Course



@admin.register(Course)

class CourseAdmin(admin.ModelAdmin):

    list_display = ("title", "price", "is_published", "created_at")

    list_filter = ("is_published",)

    search_fields = ("title", "description")

    readonly_fields = ("created_at",)



@admin.register(ContactMessage)

class ContactMessageAdmin(admin.ModelAdmin):

    list_display = ("name", "email", "created_at")

    search_fields = ("name", "email", "message")

    readonly_fields = ("name", "email", "message", "created_at")


    def has_add_permission(self, request):

        return False



admin.site.site_header = "EduShop প্রশাসন"

admin.site.site_title = "EduShop Admin"

admin.site.index_title = "ওয়েবসাইট পরিচালনা"

ব্যাখ্যা

@admin.register(Course): Course model-কে Admin Panel-এ যুক্ত করে।

list_display: তালিকায় কোন কলামগুলো দেখাবে।

list_filter: পাশ থেকে তথ্য filter করার ব্যবস্থা।

search_fields: কোন field দিয়ে search করা যাবে।

readonly_fields: যেসব তথ্য Admin-এ পরিবর্তন করা যাবে না।

has_add_permission: Admin থেকে যোগাযোগের মেসেজ তৈরি বন্ধ করেছি। মেসেজ আসবে ওয়েবসাইটের যোগাযোগ ফর্ম থেকে।

Admin ব্যবহারকারী চাইলে মেসেজ পড়তে ও মুছে ফেলতে পারবে।


১৩. যোগাযোগের Form তৈরি করো

খোলো বা তৈরি করো:


text


Copy



core/forms.py

কোড দাও:


python


Copy



from django import forms


from .models import ContactMessage



class ContactForm(forms.ModelForm):

    class Meta:

        model = ContactMessage

        fields = ["name", "email", "message"]


        widgets = {

            "name": forms.TextInput(

                attrs={

                    "placeholder": "তোমার নাম",

                    "autocomplete": "name",

                }

            ),

            "email": forms.EmailInput(

                attrs={

                    "placeholder": "name@example.com",

                    "autocomplete": "email",

                }

            ),

            "message": forms.Textarea(

                attrs={

                    "placeholder": "কী জানতে চাও?",

                    "rows": 6,

                }

            ),

        }


    def clean_message(self):

        message = self.cleaned_data["message"]


        if len(message) < 10:

            raise forms.ValidationError(

                "মেসেজটি কমপক্ষে ১০ অক্ষরের হতে হবে।"

            )


        return message

ব্যাখ্যা

ModelForm একটি model থেকে form বানাতে পারে।


python


Copy



model = ContactMessage

মানে এই form-এর তথ্য ContactMessage model অনুযায়ী হবে।


python


Copy



fields = ["name", "email", "message"]

স্পষ্টভাবে বলেছি, ব্যবহারকারী শুধু এই তিনটি field জমা দিতে পারবে। created_at নিজে থেকে বসবে।


widgets দিয়ে HTML input-এর ধরন ও বৈশিষ্ট্য ঠিক করছি।


clean_message() হলো অতিরিক্ত validation। মেসেজ ১০ অক্ষরের কম হলে গ্রহণ করবে না। Model-এর max_length=2000 অনুযায়ী সর্বোচ্চ দৈর্ঘ্যও form যাচাই করবে।


শুধু browser-এর validation যথেষ্ট নয়। Django server-এ আবার তথ্য যাচাই করবে।


১৪. তিনটি View তৈরি করো

খোলো:


text


Copy



core/views.py

কোড দাও:


python


Copy



from django.contrib import messages

from django.shortcuts import redirect, render

from django.views.decorators.http import require_http_methods, require_safe


from .forms import ContactForm

from .models import Course



@require_safe

def home(request):

    featured_courses = Course.objects.filter(is_published=True)[:3]


    return render(

        request,

        "core/home.html",

        {"featured_courses": featured_courses},

    )



@require_safe

def courses(request):

    published_courses = Course.objects.filter(is_published=True)


    return render(

        request,

        "core/courses.html",

        {"courses": published_courses},

    )



@require_http_methods(["GET", "POST"])

def contact(request):

    if request.method == "POST":

        form = ContactForm(request.POST)


        if form.is_valid():

            form.save()


            messages.success(

                request,

                "তোমার মেসেজ সফলভাবে জমা হয়েছে। ধন্যবাদ!",

            )


            return redirect("core:contact")

    else:

        form = ContactForm()

You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:44 AM

m

You

Continue





•

12:44 AM

GPT 6 Astra

GPT 6 Astra

আগের উত্তরে core/views.py-এর কোড অসম্পূর্ণ ছিল। প্রথমে ওই ফাইলের পুরো কোড নিচেরটি দিয়ে বদলে দাও। এরপর বাকি ফাইলগুলো তৈরি করে সাইট চালাব।


১৪. View-এর সম্পূর্ণ কোড

ফাইল:


text


Copy



core/views.py

python


Copy



from django.contrib import messages

from django.shortcuts import redirect, render

from django.views.decorators.http import require_http_methods, require_safe


from .forms import ContactForm

from .models import Course



@require_safe

def home(request):

    featured_courses = Course.objects.filter(is_published=True)[:3]


    return render(

        request,

        "core/home.html",

        {"featured_courses": featured_courses},

    )



@require_safe

def courses(request):

    published_courses = Course.objects.filter(is_published=True)


    return render(

        request,

        "core/courses.html",

        {"courses": published_courses},

    )



@require_http_methods(["GET", "POST"])

def contact(request):

    if request.method == "POST":

        form = ContactForm(request.POST)


        if form.is_valid():

            form.save()


            messages.success(

                request,

                "তোমার মেসেজ সফলভাবে জমা হয়েছে। ধন্যবাদ!",

            )


            return redirect("core:contact")

    else:

        form = ContactForm()


    return render(

        request,

        "core/contact.html",

        {"form": form},

    )

কীভাবে কাজ করে?

ডেটাবেস থেকে কোর্স আনা

python


Copy



Course.objects.filter(is_published=True)

শুধু প্রকাশিত কোর্স আনে। লুকানো কোর্স দর্শকের পেজে দেখাবে না।


python


Copy



[:3]

হোম পেজে সর্বোচ্চ তিনটি কোর্স দেখায়।


Template-এ তথ্য পাঠানো

python


Copy



{"courses": published_courses}

এখানে বাম পাশের "courses" নামটি দিয়ে HTML template-এ তথ্য ব্যবহার করব।


যোগাযোগ ফর্ম

GET request: খালি form দেখায়।

POST request: জমা দেওয়া তথ্য যাচাই করে।

form.is_valid(): তথ্য বৈধ কি না দেখে।

form.save(): বৈধ তথ্য ডেটাবেসে সংরক্ষণ করে।

redirect(): সফল submission-এর পরে নতুন GET request-এ নিয়ে যায়।

শেষের পদ্ধতিকে Post/Redirect/Get বলা হয়। এতে সফল submission-এর পরে browser refresh করলে একই POST আবার জমা পড়ার সাধারণ সমস্যাটি এড়ানো যায়।


ভুল তথ্য দিলে redirect হবে না; একই পেজে error-সহ form দেখাবে।


১৫. URL যুক্ত করো

১৫.১ App-এর URL

ফাইল তৈরি বা খোলো:


text


Copy



core/urls.py

python


Copy



from django.urls import path


from . import views


app_name = "core"


urlpatterns = [

    path("", views.home, name="home"),

    path("courses/", views.courses, name="courses"),

    path("contact/", views.contact, name="contact"),

]

ব্যাখ্যা

python


Copy



path("courses/", views.courses, name="courses")

এর অর্থ:


/courses/ ঠিকানায় request এলে

views.courses চালাও

এই URL-এর নাম রাখো courses

app_name = "core" থাকায় URL-টিকে core:courses নামে উল্লেখ করতে পারব। ভবিষ্যতে অন্য app-এর একই নামের URL থাকলেও বিভ্রান্তি কমবে।


১৫.২ Project-এর মূল URL

ফাইল:


text


Copy



config/urls.py

পুরো কোড বদলে দাও:


python


Copy



from django.contrib import admin

from django.urls import include, path


urlpatterns = [

    path("admin/", admin.site.urls),

    path("", include("core.urls")),

]

include("core.urls") আমাদের app-এর URL-গুলো মূল project-এর সঙ্গে যুক্ত করছে।


১৬. সব পেজের সাধারণ কাঠামো

তিনটি পেজেই header, menu ও footer থাকবে। সেগুলো বারবার না লিখে একটি base template বানাব।


ফাইল:


text


Copy



templates/base.html

html


Code


Preview


Copy




You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:45 AM

m

You

Continue





•

12:45 AM

GPT 6 Astra

GPT 6 Astra

আগের উত্তরে base.html-এর কোড মাঝপথে থেমে গেছে। ওই ফাইলের অসম্পূর্ণ কোড মুছে নিচের সম্পূর্ণ কোড বসাও। এবার বাকি ফাইলগুলো শেষ করে ওয়েবসাইট চালু করব।


প্রতিটি ফাইল লেখার পরে Ctrl + S দিয়ে save করবে। PowerShell command চালাবে djnagosite ফোল্ডারে, যেখানে manage.py আছে।


১৬. Base template-এর সম্পূর্ণ কোড

ফাইল:


text


Copy



templates/base.html

html


Code


Preview


Copy




ব্যাখ্যা

Static file যুক্ত করা

django


Copy



{% load static %}

Django-এর static template tag ব্যবহার করার সুযোগ দেয়।


django


Copy



{% static 'css/style.css' %}

CSS ফাইলের URL তৈরি করে। এটি Windows-এর filesystem path নয়।


Template block

django


Copy



{% block content %}

{% endblock %}

এখানে প্রতিটি পেজ নিজের আলাদা কনটেন্ট বসাবে। Header ও footer একই থাকবে।


Named URL

django


Copy



{% url 'core:courses' %}

আগের ধাপে দেওয়া URL-এর নাম দিয়ে লিংক তৈরি করে। পরে URL path বদলালেও template-এ সরাসরি /courses/ খুঁজে বদলাতে হবে না।


Messages

django


Copy



{{ message }}

যোগাযোগ ফর্ম সফলভাবে জমা দেওয়ার পরে Django-এর success message দেখাবে।


সক্রিয় menu

html


Code


Preview


Copy




বর্তমান পেজের লিংক চিহ্নিত করে। CSS দিয়ে সেটিকে আলাদা রঙ দেব।


১৭. হোম পেজ তৈরি করো

ফাইল:


text


Copy



templates/core/home.html

html


Code


Preview


Copy




You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:45 AM

m

You

Continue





•

12:46 AM

GPT 6 Astra

GPT 6 Astra

আগের উত্তরে হোম পেজের কোড অসম্পূর্ণ ছিল। templates/core/home.html ফাইলের সব কোড মুছে নিচের সম্পূর্ণ কোড বসাও। এবার বাকি পেজ, CSS, database ও Admin setup শেষ করে সাইট চালু করব।


এই অংশে নতুন করে project তৈরি করবে না। আগের ধাপের ফাইলগুলোই ব্যবহার করবে। প্রতিটি ফাইল save করবে এবং PowerShell command চালাবে manage.py থাকা djnagosite ফোল্ডারে।


১৭. হোম পেজের সম্পূর্ণ কোড

ফাইল:


text


Copy



templates/core/home.html

html


Code


Preview


Copy




ব্যাখ্যা

django


Copy



{% extends "base.html" %}

হোম পেজ base.html-এর header, footer ও সাধারণ কাঠামো ব্যবহার করছে।


django


Copy



{% for course in featured_courses %}

View থেকে পাঠানো featured_courses তালিকার প্রতিটি কোর্স দেখায়।


django


Copy



{{ course.title }}

একটি কোর্সের নাম দেখায়।


django


Copy



{{ course.description|truncatewords:25 }}

বিবরণ বড় হলে সংক্ষেপে প্রথম ২৫টি শব্দ পর্যন্ত দেখায়।


django


Copy



{% empty %}

কোনো কোর্স না থাকলে বিকল্প লেখা দেখায়। তাই প্রথমবার database খালি থাকলেও পেজ কাজ করবে।


১৮. কোর্সের পেজ তৈরি করো

ফাইল:


text


Copy



templates/core/courses.html

html


Code


Preview


Copy




গুরুত্বপূর্ণ বিষয়

django


Copy



{{ course.description|linebreaksbr }}

Admin-এ বিবরণ লেখার সময় নতুন লাইন দিলে সেটি পেজেও দেখাবে।


Django template সাধারণভাবে variable-এর HTML escape করে। ব্যবহারকারীর দেওয়া তথ্য দেখানোর সময় অকারণে |safe ব্যবহার করবে না—এতে অনিরাপদ HTML চালু হয়ে


You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:46 AM

m

You

Continue





•

12:47 AM

GPT 6 Astra

GPT 6 Astra

আগের কথাটির শেষ অংশ: ব্যবহারকারীর দেওয়া লেখা দেখাতে অকারণে |safe ব্যবহার করবে না—এতে ক্ষতিকর HTML বা JavaScript ঢুকে XSS vulnerability তৈরি হতে পারে। আমাদের বর্তমান template-এ এটি প্রয়োজন নেই।


এবার যোগাযোগ পেজ, CSS এবং database setup শেষ করি।


১৯. যোগাযোগ পেজ তৈরি করো

ফাইল:


text


Copy



templates/core/contact.html

সম্পূর্ণ কোড:


html


Code


Preview


Copy




ব্যাখ্যা

method="post"

ফর্মের তথ্য POST request-এর body-তে পাঠায়।


POST নিজে তথ্য encrypt করে না। লাইভ সাইটে নিরাপদ যোগাযোগের জন্য HTTPS প্রয়োজন।


{% csrf_token %}

Django-এর CSRF সুরক্ষার জন্য token যোগ করে। আগের default CsrfViewMiddleware চালু রেখো।


{{ form.as_div }}

Django form-এর label, input এবং validation error তৈরি করে। ভুল তথ্য জমা দিলে সংশ্লিষ্ট field-এর কাছে error দেখাবে।


এই form এখন শুধু database-এ মেসেজ সংরক্ষণ করে; কোনো email পাঠায় না। মেসেজ Admin Panel থেকে পড়বে।


২০. ওয়েবসাইটের CSS তৈরি করো

ফাইল:


text


Copy



static/css/style.css

সম্পূর্ণ কোড:


css


Copy



:root {

    --primary: #1d4ed8;

    --primary-dark: #1e40af;

    --text: #172033;

    --muted: #475569;

    --border: #cbd5e1;

    --background: #f8fafc;

    --surface: #ffffff;

}


* {

    box-sizing: border-box;

}


body {

    margin: 0;

    min-height: 100vh;

    display: flex;

    flex-direction: column;

    font-family: system-ui, sans-serif;

    line-height: 1.7;

    color: var(--text);

    background: var(--background);

    overflow-wrap: anywhere;

}


a {

    color: var(--primary);

    text-underline-offset: 3px;

}


a:hover {

    color: var(--primary-dark);

}


a:focus-visible,

button:focus-visible,

input:focus-visible,

textarea:focus-visible {

    outline: 3px solid #7c3aed;

    outline-offset: 4px;

}


h1,

h2,

h3 {

    line-height: 1.35;

}


h1 {

    font-size: clamp(2rem, 5vw, 3.3rem);

}


h2 {

    font-size: 1.65rem;

}


p {

    margin-top: 0;

}


.container {

    width: min(1120px, 92%);

    margin-inline: auto;

}


.main-content {

    flex: 1;

    padding-block: 32px 64px;

}


.site-header {

    background: var(--surface);

    border-bottom: 1px solid var(--border);

}


.header-inner {

    display: flex;

    justify-content: space-between;

    align-items: center;

    gap: 20px;

    padding-block: 18px;

}


.brand {

    font-size: 1.6rem;

    font-weight: 800;

    text-decoration: none;

}


.nav-links {

    display: flex;

    flex-wrap: wrap;

    gap: 8px;

}


.nav-links a {

    padding: 8px 12px;

    border-radius: 8px;

    color: var(--muted);

    text-decoration: none;

    font-weight: 600;

}


.nav-links a:hover,

.nav-links a[aria-current="page"] {

    color: var(--primary);

    background: #eff6ff;

}


.skip-link {

    position: absolute;

    top: 8px;

    left: 8px;

    transform: translateY(-180%);

    z-index: 10;

    padding: 10px 16px;

    background: white;

    border: 2px solid var(--primary);

}


.skip-link:focus {

    transform: translateY(0);

}


.hero {

    padding: clamp(28px, 6vw, 64px);

    border: 1px solid #bfdbfe;

    border-radius: 20px;

    background: linear-gradient(135deg, #eff6ff, #eef2ff);

}


.hero h1 {

    max-width: 780px;

    margin-top: 12px;

}


.eyebrow {

    color: var(--primary);

    font-weight: 700;

}


.hero-description {

    max-width: 680px;

    font-size: 1.1rem;

    color: var(--muted);

}


.button-row {

    display: flex;

    flex-wrap: wrap;

    gap: 12px;

    margin-top: 24px;

}


.button {

    display: inline-block;

    padding: 11px 18px;

    border: 1px solid var(--primary);

    border-radius: 9px;

    background: var(--primary);

    color: white;

    font: inherit;

    font-weight: 600;

    text-align: center;

    text-decoration: none;

    cursor:

You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:47 AM

m

You

Continue





•

12:47 AM

GPT 6 Astra

GPT 6 Astra

আগের CSS কোডটি cursor: লাইনে থেমে গেছে। static/css/style.css ফাইলে ওই অসম্পূর্ণ cursor: লাইনটি মুছে নিচের কোড সেখান থেকে বসাও। আগের CSS রেখে দেবে।


css


Copy



    cursor: pointer;

}


.button:hover {

    background: var(--primary-dark);

    border-color: var(--primary-dark);

    color: white;

}


.button-secondary {

    background: white;

    color: var(--primary);

}


.button-secondary:hover {

    background: #eff6ff;

    color: var(--primary-dark);

}


.section {

    margin-top: 48px;

}


.section-heading {

    display: flex;

    justify-content: space-between;

    align-items: center;

    flex-wrap: wrap;

    gap: 12px;

    margin-bottom: 20px;

}


.section-heading h2 {

    margin: 0;

}


.card-grid {

    display: grid;

    grid-template-columns: repeat(3, minmax(0, 1fr));

    gap: 20px;

}


.card {

    min-width: 0;

    padding: 24px;

    border: 1px solid var(--border);

    border-radius: 14px;

    background: var(--surface);

    box-shadow: 0 4px 16px rgb(15 23 42 / 4%);

}


.card h3 {

    margin-top: 12px;

}


.card p,

.course-description {

    color: var(--muted);

}


.course-card {

    display: flex;

    flex-direction: column;

    align-items: flex-start;

}


.course-card .button {

    margin-top: auto;

}


.badge {

    display: inline-block;

    padding: 3px 10px;

    border-radius: 999px;

    background: #dbeafe;

    color: #1e40af;

    font-size: 0.85rem;

    font-weight: 700;

}


.card .price {

    margin-block: 20px;

    color: var(--primary);

    font-size: 1.3rem;

    font-weight: 800;

}


.empty-state {

    grid-column: 1 / -1;

    padding: 24px;

    border: 1px dashed var(--border);

    border-radius: 12px;

    color: var(--muted);

    background: white;

}


.page-heading {

    max-width: 760px;

    margin-bottom: 32px;

}


.page-heading h1 {

    margin-block: 10px 16px;

}


.contact-panel {

    max-width: 720px;

    padding: 28px;

    border: 1px solid var(--border);

    border-radius: 14px;

    background: var(--surface);

}


form > div {

    margin-bottom: 20px;

}


label {

    display: block;

    margin-bottom: 6px;

    font-weight: 600;

}


input,

textarea {

    width: 100%;

    padding: 12px;

    border: 1px solid #64748b;

    border-radius: 8px;

    background: white;

    color: var(--text);

    font: inherit;

}


textarea {

    min-height: 160px;

    resize: vertical;

}


input[aria-invalid="true"],

textarea[aria-invalid="true"] {

    border-color: #b91c1c;

}


.errorlist {

    margin-block: 8px;

    padding-left: 24px;

    color: #b91c1c;

}


.form-summary {

    padding: 12px 16px;

    border: 1px solid #fecaca;

    border-radius: 8px;

    background: #fef2f2;

    color: #991b1b;

}


.helptext {

    display: block;

    margin-top: 6px;

    color: var(--muted);

    font-size: 0.9rem;

}


.notice {

    padding: 14px 18px;

    border: 1px solid #86efac;

    border-radius: 10px;

    background: #f0fdf4;

    color: #166534;

}


.site-footer {

    padding-block: 24px;

    border-top: 1px solid var(--border);

    background: white;

    color: var(--muted);

    text-align: center;

}


.site-footer p {

    margin: 0;

}


@media (max-width: 900px) {

    .card-grid {

        grid-template-columns: repeat(2, minmax(0, 1fr));

    }

}


@media (max-width: 600px) {

    .header-inner {

        flex-direction: column;

        align-items: flex-start;

    }


    .card-grid {

        grid-template-columns: 1fr;

    }


    .hero,

    .contact-panel {

        padding: 24px 18px;

    }


    .nav-links a {

        padding: 8px 10px;

    }

}

এতে বড় পর্দায় তিন কলাম, মাঝারি পর্দায় দুই কলাম এবং মোবাইলে এক কলামে card দেখাবে।


২১. Settings একবার যাচাই করো

খোলো:


text


Copy



config/settings.py

পুরো ফাইল বদলাবে না। নিচের বিষয়গুলো মিলিয়ে নাও।


২১.১ App registration

INSTALLED_APPS-এ Django-এর default app-গুলো রেখে "core" যোগ করা থাকতে হবে:


python


Copy



INSTALLED_APPS = [

    "django.contrib.admin",

    "django.contrib.auth",

    "django.contrib.contenttypes",

    "django.contrib.sessions",

    "django.contrib.messages",

    "django.contrib.staticfiles",

    "core",

]

আগে থেকেই "core.apps.CoreConfig" থাকলে সেটি রাখো; পাশাপাশি "core" আবার যোগ করবে না।


২১.২ Template folder

TEMPLATES-এর মধ্যে DIRS এমন হবে:


python


Copy



"DIRS": [BASE_DIR / "templates"],

একই configuration-এ এটি থাকবে:


python


Copy



"APP_DIRS": True,

Default context_processors-এ নিচেরগুলো রেখো:


python


Copy



"django.template.context_processors.request",

"django.contrib.auth.context_processors.auth",

"django.contrib.messages.context_processors.messages",

এগুলো request, login-সং


You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:47 AM

m

You

Continue





•

12:48 AM

GPT 6 Astra

GPT 6 Astra

এগুলো template-এ যথাক্রমে request-এর তথ্য, login-সংক্রান্ত তথ্য এবং success/error message ব্যবহার করতে সাহায্য করে।


এবার settings যাচাই শেষ করে সাইট চালু করি।


২১.৩ Static file-এর settings

config/settings.py-এ নিচের settings থাকবে:


python


Copy



STATIC_URL = "static/"


STATICFILES_DIRS = [

    BASE_DIR / "static",

]

একই setting আগে থেকে থাকলে নতুন করে আবার লিখবে না; সেটি প্রয়োজনমতো ঠিক করবে।


এতে Django আমাদের এই ফাইলটি খুঁজে পাবে:


text


Copy



static/css/style.css

২১.৪ Middleware রেখে দাও

Default MIDDLEWARE-এর এই entry-গুলো সরাবে না:


python


Copy



"django.contrib.sessions.middleware.SessionMiddleware",

"django.middleware.csrf.CsrfViewMiddleware",

"django.contrib.auth.middleware.AuthenticationMiddleware",

"django.contrib.messages.middleware.MessageMiddleware",

এগুলো session, CSRF protection, authentication এবং messages-এর জন্য প্রয়োজন। উপরের তালিকা দিয়ে পুরো MIDDLEWARE বদলাবে না—বাকি default entry-গুলোও রেখো।


২২. ফাইলের কাঠামো মিলিয়ে নাও

প্রয়োজনীয় ফাইলগুলো এমন জায়গায় থাকবে:


text


Copy



djnagosite/

├── manage.py

├── config/

│   ├── settings.py

│   └── urls.py

├── core/

│   ├── migrations/

│   ├── admin.py

│   ├── forms.py

│   ├── models.py

│   ├── urls.py

│   └── views.py

├── templates/

│   ├── base.html

│   └── core/

│       ├── home.html

│       ├── courses.html

│       └── contact.html

└── static/

    └── css/

        └── style.css

এখানে শুধু প্রয়োজনীয় অংশ দেখানো হয়েছে। অন্য default ফাইলগুলো মুছবে না।


২৩. Database table তৈরি করো

PowerShell-এ manage.py থাকা ফোল্ডারে যাও। আগের ধাপে তৈরি virtual environment সক্রিয় আছে কি না নিশ্চিত হও।


প্রথমে চালাও:


powershell


Copy



python manage.py check

কোনো সমস্যা না পেলে সাধারণত দেখাবে:


text


Copy



System check identified no issues (0 silenced).

এরপর:


powershell


Copy



python manage.py makemigrations core

python manage.py migrate

কোন command কী করে?

makemigrations core: model-এর পরিবর্তন থেকে migration file তৈরি করে।

migrate: migration অনুযায়ী database-এর table তৈরি বা পরিবর্তন করে।

আগে migration তৈরি করা থাকলে No changes detected দেখানো স্বাভাবিক।


কোনো command-এ error হলে আগে সেটি ঠিক করবে; error উপেক্ষা করে পরের command চালাবে না।


২৪. Admin ব্যবহারকারী তৈরি করো

চালাও:


powershell


Copy



python manage.py createsuperuser

তারপর terminal-এর নির্দেশনা অনুযায়ী username, email এবং password দাও।


Password টাইপ করার সময় terminal-এ অক্ষর বা তারকা না দেখানো স্বাভাবিক। Password লিখে Enter চাপবে।


শক্তিশালী ও আলাদা password ব্যবহার করো।


২৫. Development server চালাও

চালাও:


powershell


Copy



python manage.py runserver

Server চালু থাকলে browser-এ খোলো:


text


Copy



http://127.0.0.1:8000/

এখন এই ঠিকানাগুলো দেখতে পারবে:


পেজ ঠিকানা

হোম http://127.0.0.1:8000/

কোর্স http://127.0.0.1:8000/courses/

যোগাযোগ http://127.0.0.1:8000/contact/

Admin http://127.0.0.1:8000/admin/

Server বন্ধ করতে terminal-এ চাপবে:


text


Copy



Ctrl + C

এটি এখন তোমার কম্পিউটারে চলা local website—ইন্টারনেটে প্রকাশিত live site নয়।


২৬. Admin থেকে কোর্স যোগ করো

১. /admin/ ঠিকানায় যাও।


২. তৈরি করা superuser দিয়ে login করো।


৩. Courses-এর পাশে Add চাপো।


৪. কোর্সের তথ্য দাও।


উদাহরণ:


text


Copy



Title: Python শেখার শুরু


Description:

এই কোর্সে Python-এর variable, condition, loop ও function শেখানো হবে।

ছোট প্রজেক্টের মাধ্যমে অনুশীলন করা হবে।


Price: 1500.00


Is published: চালু

৫. Save চাপো।


৬. কোর্সের পেজ refresh করো।


কোর্সটি এখন দেখা যাওয়ার কথা। Is published বন্ধ করে save করলে public page-এ আর দেখাবে না।


নতুন কোর্স আগে দেখানোর ছোট সংশোধন

হোম পেজে আমরা “নতুন কোর্স” লিখেছি। সেটি নিশ্চিত করতে core/views.py-এর সংশ্লিষ্ট query দুটো এভাবে লিখতে পারো:


home()-এর মধ্যে:


python


Copy



featured_courses = Course.objects.filter(

    is_published=True

).order_by("-created_at", "-pk")[:3]

courses()-এর মধ্যে:


python


Copy



published_courses = Course.objects.filter(

    is_published=True

).order_by("-created_at", "-pk")

এতে সর্বশেষ তৈরি কোর্স আগে আসবে। এখানে শুধু query বদলাবে; view-এর বাকি কোড রাখবে।


২৭. যোগাযোগ ফর্ম পরীক্ষা করো

যোগাযোগ পেজে গিয়ে নাম, email ও অন্তত ১০ অক্ষরের একটি মেসেজ দিয়ে submit করো।


উদাহরণ:


text


Copy



নাম: পরীক্ষামূলক ব্যবহারকারী

ইমেইল: learner@example.com

মেসেজ: Python কোর্স সম্পর্কে বিস্তারিত জানতে চাই।

সফল হলে confirmation message দেখাবে।


এরপর Admin Panel-এর Contact messages তালিকায় গিয়ে মেসেজটি দেখো।


এই পরীক্ষাগুলোও করো

নাম খালি রেখে submit করার চেষ্টা।

ভুল email দিয়ে submit করার চেষ্টা।

১০ অক্ষরের কম মেসেজ পাঠানো।

সঠিক

You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:49 AM

m

You

Continue





•

12:49 AM

GPT 6 Astra

GPT 6 Astra

সঠিক তথ্য দিয়ে submit করে success message দেখা।

সফল submission-এর পরে পেজ refresh করে নতুন মেসেজ আবার জমা হচ্ছে কি না দেখা।

Admin Panel-এ সংরক্ষিত তথ্য ঠিক আছে কি না যাচাই করা।

ছোট স্পষ্টীকরণ: মেসেজের “কমপক্ষে ১০ অক্ষর” নিয়মটি তখনই কার্যকর হবে, যখন আগের ContactForm বা model-এ সেই validation লেখা আছে। শুধু HTML template এই নিয়ম তৈরি করে না।


২৮. ছোট মেসেজ আটকানোর validation

যদি আগের ContactForm-এ এই validation না থাকে, তাহলে core/forms.py-এ বিদ্যমান ContactForm class-এর ভেতরে নিচের method যোগ করো।


ফাইলের উপরে এই import থাকতে হবে:


python


Copy



from django import forms

Class-এর ভেতরে যোগ করবে:


python


Copy



    def clean_message(self):

        message = self.cleaned_data.get("message", "").strip()


        if len(message) < 10:

            raise forms.ValidationError(

                "মেসেজে অন্তত ১০টি অক্ষর লিখো।"

            )


        return message

খেয়াল রাখবে:


এখানে form field-এর নাম message ধরে নেওয়া হয়েছে।

clean_message() আগে থেকেই থাকলে নতুন আরেকটি তৈরি না করে আগেরটি সংশোধন করো।

এটি ContactForm class-এর method হবে, Meta class-এর ভেতরে নয়।

শুধু form validation পরিবর্তন করলে database migration প্রয়োজন নেই।

এবার ছোট মেসেজ পাঠালে error দেখাবে এবং বৈধ না হওয়ায় view সেটি save করবে না।


২৯. কোর্সের ordering নিয়ে একটি যাচাই

আগের ধাপে ব্যবহার করেছিলাম:


python


Copy



.order_by("-created_at", "-pk")

এটি কাজ করতে Course model-এ created_at field থাকতে হবে।


ওই field না থাকলে, আপাতত query দুটো এভাবে লিখতে পারো:


home()-এর মধ্যে:


python


Copy



featured_courses = (

    Course.objects

    .filter(is_published=True)

    .order_by("-pk")[:3]

)

courses()-এর মধ্যে:


python


Copy



published_courses = (

    Course.objects

    .filter(is_published=True)

    .order_by("-pk")

)

Default auto-increment primary key ব্যবহার করলে এতে সাধারণভাবে পরে যোগ করা কোর্স আগে আসবে। তবে এটি প্রকৃত creation timestamp দিয়ে সাজানোর বিকল্প নয়।


৩০. সাধারণ error ও সমাধান

৩০.১ TemplateDoesNotExist

যেমন:


text


Copy



TemplateDoesNotExist: core/home.html

যাচাই করো ফাইলটি এখানে আছে কি না:


text


Copy



templates/core/home.html

এবং config/settings.py-এর TEMPLATES-এ:


python


Copy



"DIRS": [BASE_DIR / "templates"],

ফাইলের নাম ভুল করে home.html.txt হয়ে গেছে কি না-ও দেখো।


৩০.২ CSS দেখা যাচ্ছে না

প্রথমে নিশ্চিত হও:


text


Copy



static/css/style.css

ফাইলটি আছে।


তারপর terminal-এ চালাও:


powershell


Copy



python manage.py findstatic css/style.css

পাওয়া গেলে Django ফাইলটির অবস্থান দেখাবে।


এরপর browser-এ hard refresh করো:


text


Copy



Ctrl + F5

লোকাল development-এ DEBUG = True এবং django.contrib.staticfiles চালু থাকলে runserver সাধারণত static file serve করে। লাইভ সাইটে একই ব্যবস্থা ব্যবহার করা যাবে না।


৩০.৩ no such table: core_course

সাধারণত database migration প্রয়োগ করা হয়নি।


চালাও:


powershell


Copy



python manage.py makemigrations core

python manage.py migrate

Migration-এর অবস্থা দেখতে:


powershell


Copy



python manage.py showmigrations core

প্রয়োগ করা migration-এর পাশে [X] দেখাবে।


৩০.৪ Admin-এ Courses দেখা যাচ্ছে না

core/admin.py-এ Course register করা আছে কি না দেখো।


আগে register করা না থাকলে সর্বনিম্ন কোড:


python


Copy



from django.contrib import admin


from .models import Course


admin.site.register(Course)

আগে থেকেই @admin.register(Course) বা admin.site.register(Course) থাকলে আবার register করবে না। বিদ্যমান অন্য model registration-ও মুছবে না।


যোগাযোগের মেসেজ দেখতে সেটির model-ও Admin-এ register থাকতে হবে।


৩০.৫ CSRF verification failed

নিশ্চিত হও form-এর ভেতরে আছে:


django


Copy



{% csrf_token %}

এবং default CSRF middleware চালু আছে।


Admin login করার পরে পুরোনো খোলা form submit করলে token বদলের কারণে এমন হতে পারে। যোগাযোগ পেজ reload করে আবার চেষ্টা করো।


এটি ঠিক করতে @csrf_exempt যোগ করে সুরক্ষা বন্ধ করবে না।


৩০.৬ Port আগে থেকেই ব্যবহার হচ্ছে

অন্য port-এ চালাও:


powershell


Copy



python manage.py runserver 8001

তারপর খোলো:


text


Copy



http://127.0.0.1:8001/

৩১. শেষবারের মতো পরীক্ষা

পরীক্ষা প্রত্যাশিত ফল

হোম পেজ খোলা Header, hero, course card ও footer দেখা

কোর্সের পেজ খোলা শুধু প্রকাশিত কোর্স দেখা

কোর্স unpublished করা Public page থেকে কোর্সটি সরে যাওয়া

সঠিক যোগাযোগ ফর্ম জমা Success message এবং database-এ রেকর্ড

ভুল তথ্য জমা Validation error; নতুন রেকর্ড না হওয়া

সফল submission-এর পরে refresh সাধারণ refresh-এ একই POST আবার না হওয়া

Browser ছোট করা Card এক কলামে চলে আসা

কিবোর্ডে Tab চাপা Link ও form control-এ দৃশ্যমান focus

Post/Redirect/Get সাধারণ refresh-


You ran out of credits

This answer stopped because it used up your remaining credits. Your progress is saved, so you can pick up right where it left off. Upgrade










•

12:50 AM

m

You

Continue





•

12:50 AM

GPT 6 Astra

GPT 6 Astra

Post/Redirect/Get সাধারণ refresh-এর সময় একই form আবার submit হওয়া ঠেকায়। তবে দ্রুত দুবার submit করা বা একই request পুনরায় পাঠানোর সব পরিস্থিতি এটি আটকায় না।


এবার শেষ কয়েকটি বিষয় মিলিয়ে নিই।


৩২. সফল submission-এর পরে redirect নিশ্চিত করো

যোগাযোগ form বৈধ হলে view-এর কাজের ক্রম হবে:


মেসেজ save করা।

Success message যোগ করা।

যোগাযোগ পেজে redirect করা।

আগের ContactForm যদি ModelForm হয়, তাহলে core/views.py-এর contact() view এমন হতে পারে:


python


Copy



from django.contrib import messages

from django.shortcuts import redirect, render


from .forms import ContactForm



def contact(request):

    if request.method == "POST":

        form = ContactForm(request.POST)


        if form.is_valid():

            form.save()


            messages.success(

                request,

                "তোমার মেসেজ জমা হয়েছে। ধন্যবাদ!",

            )


            return redirect("core:contact")

    else:

        form = ContactForm()


    return render(

        request,

        "core/contact.html",

        {"form": form},

    )

পুরো views.py এই কোড দিয়ে বদলাবে না। বিদ্যমান home() ও courses() রাখবে। প্রয়োজন হলে শুধু contact() সংশোধন করবে এবং অনুপস্থিত import যোগ করবে।


ContactForm যদি সাধারণ forms.Form হয়, তাহলে সরাসরি form.save() কাজ করবে না। সে ক্ষেত্রে আগের view-এর database-এ save করার কোড রাখবে।


ভুল তথ্য দিলে কী হবে?

form.is_valid() মিথ্যা হলে redirect হবে না। একই bound form template-এ ফেরত যাবে, যাতে ব্যবহারকারী নিজের লেখা এবং সংশ্লিষ্ট error দেখতে পারে।


৩৩. পরের দিন আবার সাইট চালু করবে যেভাবে

প্রতিবার নতুন করে project, migration বা superuser তৈরি করতে হবে না।


১. PowerShell খুলে manage.py থাকা ফোল্ডারে যাও।


২. আগের virtual environment সক্রিয় করো। যেমন, সেটির নাম .venv হলে:


powershell


Copy



.\.venv\Scripts\Activate.ps1

তোমার environment-এর নাম অন্য হলে সেই নাম ব্যবহার করবে।


৩. Server চালাও:


powershell


Copy



python manage.py runserver

৪. Browser-এ খোলো:


text


Copy



http://127.0.0.1:8000/

কখন কোন command লাগবে?

পরিবর্তন করণীয়

HTML বা CSS পরিবর্তন Save করে browser refresh

Python view বা form পরিবর্তন Save; development server সাধারণত reload করবে

Model-এর database field পরিবর্তন makemigrations, তারপর migrate

Server বন্ধ হয়ে গেছে আবার runserver

নতুন admin দরকার প্রয়োজন অনুযায়ী createsuperuser

নতুন ফাইল যোগ করার পর পরিবর্তন ধরা না পড়লে server বন্ধ করে আবার চালাও।


৩৪. Local project আর live website এক নয়

এখনকার setup শেখা ও local development-এর জন্য। ইন্টারনেটে প্রকাশ করার আগে অন্তত নিচের বিষয়গুলো ঠিক করতে হবে:


DEBUG = False করা।

নিজের domain অনুযায়ী ALLOWED_HOSTS নির্ধারণ করা।

SECRET_KEY ও অন্যান্য গোপন তথ্য environment variable-এ রাখা।

HTTPS চালু করা এবং প্রয়োজনমতো secure cookie settings করা।

runserver-এর বদলে production WSGI/ASGI server ব্যবহার করা।

Static file পরিবেশনের ব্যবস্থা করা।

Database backup রাখা।

যোগাযোগ form-এ spam ও অতিরিক্ত request নিয়ন্ত্রণের ব্যবস্থা করা।

Django ও dependency-গুলোর security update রাখা।

Production settings দিয়ে এই command চালিয়ে configuration-এর সতর্কতা পরীক্ষা করবে:


powershell


Copy



python manage.py check --deploy

এটি সহায়ক পরীক্ষা; পূর্ণ security audit নয়।


৩৫. এই ধাপে কী তৈরি হলো?

সব পরীক্ষা ঠিক থাকলে তোমার EduShop-এর প্রাথমিক সংস্করণ প্রস্তুত:


হোম পেজ।

Database থেকে প্রকাশিত কোর্সের তালিকা।

কোর্সের বিবরণ ও মূল্য।

Validation-সহ যোগাযোগ form।

Admin থেকে কোর্স পরিচালনা।

Admin থেকে যোগাযোগের মেসেজ দেখা।

মোবাইল উপযোগী layout।

এখনও course purchase, payment, শিক্ষার্থীর account বা lesson access তৈরি হয়নি। বর্তমান সংস্করণটি একটি course catalog ও যোগাযোগভিত্তিক ওয়েবসাইট।


পরের feature যোগ করার আগে হোম → কোর্স → যোগাযোগ → Admin—এই চারটি অংশ একবার পরীক্ষা করে নাও। কোনো error হলে terminal-এর সম্পূর্ণ error message এবং সংশ্লিষ্ট ফাইলের কোড পাঠাবে—password, SECRET_KEY বা ব্যক্তিগত তথ্য বাদ দিয়ে।

Post a Comment

0 Comments

Post a Comment (0)