বাংলায় জ্যাঙ্গো

Uncategorized

মডেল রিলেশন ও জ্যাঙ্গো এডমিন কাষ্টমাইজেশন

by , on
March 16, 2017

আজকে আমরা একটা মজার এপ তৈরী করব। আমাদের পেজে বাংলাদেশের বিভাগগুলির নাম দেখাব এবং ওই বিভাগে ক্লিক করলে তার জেলাগুলো দেখাবে। এবং জেলাতে চাপলে ওই জেলা সম্পর্কে তথ্য দেখাবে।

পরিকল্পনাঃ আমরা নতুন একরটি এপ তৈরী করব। ১ম ধাপে জেলা এবং বিভাগের লিষ্ট দখানোর জন্য দুইটি মডেল দরকার। জেলা মডেলের মধ্য বলে দেব সে কোন বিভাগের অন্তর্গত । ২য় ধাপে জেলার বর্ননা তৈরীর জন্য আরেকটি মডেল তৈরী করব এবং এই বর্ননা কোন জেলার তা বলে দেব। তো কাজ শুরু করা যাক……

python manage.py startapp information

information নামে একটি নতুন এপ তৈরী করলাম।

INSTALLED_APPS এর মধ্যে information কে যুক্ত করি।

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog_post',
    'cost_management',
    'information',
]

information/models.py এ জেলা ও বিভাগের জন্য মডেল তৈরী করি

from django.db import models


class Divisions(models.Model):
    name = models.CharField(max_length=50)
    population = models.IntegerField()
    area = models.IntegerField()

    def __str__(self):
        return self.name


class Districts(models.Model):
    name = models.CharField(max_length=50)
    education_rate = models.IntegerField()
    population_density = models.IntegerField(blank=True, null=True)
    visited = models.BooleanField(default=False)
    division = models.ForeignKey(Divisions, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

blank=True, null=True অর্থ আপনি যদি ফর্ম পুরন করার সময় population_density ফিল্ডটি ফাকা রাখতে পারবেন। visited ফিল্ডে BooleanField ব্যাবহার করা হয়েছে । আপনি জেলাটিতে পরিদর্শন করলে True , না করলে False ব্যাবহার করতে পারবেন। যদি কিছুই না দিতে চান তাহলে ডিফল্ট হিসেবে False বসাবে(default=False)division_name ফিল্ডটিতে ForeignKey ফিল্ড ব্যাবহার করেছি। এই জেলাটি কোন জেলার সদস্য তা বোঝাতে আমরা এই রিলেশনাল ফিল্ড ব্যাবহার করেছি। এছাড়াও জ্যাঙ্গো OnToOneField, ManyToManyField ব্যাবহার করে থাকে ।

বিস্তারিত দেখতে 

ডাটাবেজ তৈরী করার জন্য মাইগ্রেশন করি

python manage.py makemigrations
python manage.py migrate

এডমিন প্যনেল ব্যাবহার করে তথ্য যুক্ত করার জন্য admin.py Districts Divisions ক্লাস দুটি যুক্ত করি।

#informations/admin.py

from django.contrib import admin
from information.models import Divisions, Districts

admin.site.register(Divisions)
admin.site.register(Districts)

এখন এডমিন প্যানেলে(localhost:8000/admin) লগিন করে প্রথমে কিছু বিভাগ অতঃপর জেলা যুক্ত করি।

এডমিন পাতা কাষ্টমাইজ করা

বর্তমানে আমাদের এডমিন পাতায় শুধু জেলা বা বিভাগের লিষ্ট দেখাছে । কিন্ত আমরা যদি চাই নামের পাশে আন্যান্য ফিল্ড ও টেবিলের মত দেখায়। admin.ModelAdmin ক্লাস আমাদের সাজানোর কাজ করে দেবে। জেলা লিষ্ট কে টেবিলের মত দেখানোর জন্য নিচের কোড লিখি

information/admin.py

class DistrictAdmin(admin.ModelAdmin):
    list_display = ('name','division', 'visited','population_density')

একটি নতুন ক্লাস তৈরী করেছি যেটা admin.ModelAdmin ক্লাসকে ইনহেরিট করেছে। list_display এর মধ্যে আপনি যে ফিল্ডগুলো কলাম আকারে দেখাতে চান তা যুক্ত করি।

এখন admin.site.register(Districts) এর মধ্যে DistrictAdmin কে যুক্ত করি। আমরা যদি Divisions মডেলকে পরিবর্তন করতে চাই তাহলে admin.site.register(Divisions) এর মধ্যে নতুন ক্লাস প্রবেশ করাতে হবে।

from django.contrib import admin
from information.models import Divisions, Districts

class DistrictAdmin(admin.ModelAdmin):
    list_display = ('name','division', 'visited','population_density')

admin.site.register(Divisions)
admin.site.register(Districts, DistrictAdmin)

 

আজ এ পর্যন্তই, আরো পরিবর্তন করতে ডকুমেন্টেশন দেখুন। পরবর্তি পোষ্টে আমরা বিভাগ ও জেলা লিষ্ট তৈরী করব

পরবর্তি পোষ্টঃ জ্যাঙ্গো ফিল্টার  >>

Uncategorized

ভুল সংশোধনঃ single_post() got an unexpected keyword argument ‘post_id’

by , on
March 11, 2017

আমরা প্রত্যেকেই জ্যাঙ্গো শেখার শুরুতে খুব সাধারণ কিছু ভুল করে থাকি। আজ এরকম একটি ভুল আমরা কতভাবে করে থাকি তা বর্ননা করার চেষ্টা করব।

single_post() got an unexpected keyword argument ‘post_id’

কারন১ঃ variable এর নাম এক না হওয়া

আমাদের single post এর url ছিল

# blog_post/urls.py

url(r'^single-post/(?P<post_id>[0-9]+)/', views.single_post, name='single-post')

আমাদের variable এর নাম post_id এবং ভিউ single_post

#blog_post/views.py

def single_post(request, id):
    post = Post.objects.get(pk=id)
    return render(request, 'single_post.html', {'post':post})

লক্ষ করি , আমি single_post(request, id) প্যারামিটার হিসেবে id ব্যাবহার করেছি। কিন্তু url post_id ব্যাবহার করেছি। এই দুই variable এর নাম একই না হলে error দেখাবে

কারন২ঃ template url templatetag ভুল লেখা

পোষ্ট লিষ্ট লেখানোর জন্য templates/post_list.html ব্যাবহার করেছি

<h3><a href="{% url 'single-post' post.pk %}">{{ post.title }}</a></h3>

এখানে ‘single-post’ হচ্ছে url এর (blog_post/urls.py) name=’single-post’ । সুতরাং এই দুইটি একই নাম হতে হবে। অনেক সময় আমরা _ ও – এর মধ্যে পার্থক্য নির্ণয়ে ভুল করে ফেলি। আবার {% url single-post post.pk %} এভাবে লিখে ফেলি , অর্থাৎ, ‘’ (inverted comma) দিতে ভুলে যায়।

{% url ‘single-post’ %} এভাবে দেয় , অর্থাৎ প্যারামিটার হিসেবে post.pk অথবা post.id দিতে ভুলে যায়।

Uncategorized

ফর্ম তৈরী – শেষ পর্ব

by , on
March 8, 2017

আজকের পর্বে আমরা খরচ হিসাবের ফর্মটি সম্পুর্ণ করব। অর্থাৎ, আমরা http://localhost:8000/cost/add/ পেজ থেকেই আমাদের নতুন খরচের হিসাব যোগ করতে পারবো।

templates/costs/add_expense.html টেমপ্লেটকে আদর্শ রুপ দেয়।

{% extends 'base.html' %}

{% block content %}
    <form method="POST" class="form-horizontal"> {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn btn-default">Save</button>
    </form>

{% endblock %}

আমাদের form কোডকে <form></form> টেমপ্লেট ট্যাগ এর মধ্যে প্রবেশ করিয়েছি। আমরা এই ফর্ম এর মাধ্যমে কিছু ডাটা save করব তাই আমাদের viewকে POST request পাঠাতে হবে। method=”POST” এই কাজটি করবে। {% csrf_token %} হচ্ছে একটি টেমপ্লেট ট্যাগ। ফর্ম এর মাধ্যমে সকল অনৈতিক কার্জক্রম থেকে আত্নরক্ষা করার জন্য জ্যাঙ্গো আমাদেরকে এই ট্যাগটি উপহার দিয়েছে। csrf_token সম্পর্কে বিস্তারিত দেখুন।

ফর্ম পুরন করে Save বোতাম চাপুন । কি হচ্ছে ? কিছুই হচ্ছে না। শুধু লেখাগুল মুছে যাচ্ছে।

আমাদের add_expense() ভিউ( def add_expense(request): ) request প্যারামিটার গ্রহন করে। এই প্যারামিটারটিকে আমরা ২ ধরনের request পাঠাচ্ছি। ১) যখন প্রথম পেজ লোড হয় তখন GET এবং ২)যখন ডাটা সহ পেজকে Save করি তখন POST রিকুয়েষ্ট । একটু যাচাই করা যাক ,

add_expense() এর শুরুতে একটি টেষ্ট করার জন্য print যুক্ত করি।

def add_expense(request):

print(“in add expense”)

…………………..

এখন http://localhost:8000/cost/add/ পাতাটিকে আবার রিলোড করে(F5) টার্মিনালে লক্ষ করি ।

আমাদের ভিউ /cost/add/ GET রিকুয়েষ্ট গ্রহন করেছে এবং Expense ফর্মটি শুন্য ফর্ম টেমপ্লেটে পাঠাচ্ছে। ফর্মটি পুরন করে Save বোতাম চেপে আবার টার্মিনালে লক্ষ করি।

এখন আমাদের ভিউ POST রিকুয়েষ্ট গ্রহন করেছে।

এখন আমাদের ভিউকে বলতে পারি, যদি তুমি POST রিকুয়েষ্ট পাও তাহলে ফর্মটি save করার ব্যাবস্থা কর। অন্যথায় টেম্পলেটে খালি ফর্ম দেখাও ।

if request.method == 'POST':
    ………….
else:
    form = ExpenseForm

এখন request এর সাথে যে ডাটা আমরা পেয়েছি তা ফর্ম ক্লাসের মধ্যে প্রবেশ করাব

if request.method == 'POST':
    form = ExpenseForm(request.POST)
else:
    form = ExpenseForm

request.POST আমাদের ফর্ম ডাটা বহন করছে। এখন ফর্ম পুরন করে Save বোতাম চাপুন। এখন কিন্তু আর ফর্ম খালি হয়ে যাচ্ছে না। এখন form = ExpenseForm(request.POST) কাজ করছে এবং পুরনকৃত ফর্ম দেখতে পাচ্ছি। save() ম্যাথড এর মাধ্যমে আমরা ফর্ম সেভ করতে পারি।

def add_expense(request):
    if request.method == 'POST':
        form = ExpenseForm(request.POST)
        form.save()
    else:
        form = ExpenseForm
    return render(request, 'cost/add_expense.html', {'form': form})

http://localhost:8000/cost/add/ পেজটি রিলোড দিয়ে ফর্ম পূরন করে Save বোতাম চাপি। কিছুই হচ্ছে না ? হতাশ হচ্ছেন কেন !!! খরচ তালিকার পাতায়( http://localhost:8000/cost/list/ ) গিয়ে দেখুন আপনার সর্বশেষ খরচটি যোগ হয়েছে। নিশ্চয় অনেক মজা পেয়েছেন। তাহলে আজকের সকল খরচ এভাবে যুক্ত করে ফেলুন।

আমরা যখন ফর্ম পূরন করে Save বোতাম চাপি তখন কোন পরিবর্তন দেখতে পাচ্ছি না। আমাদের ভিউকে আমরা বলতে পরি, ফর্ম Save হলে খরচ তালিকা পাতায় নিয়ে যাও

cost_management/views.py এর শুরুতে যুক্ত করি

from django.shortcuts import redirect

অতঃপর যুক্ত করি

if request.method == 'POST':
    form = ExpenseForm(request.POST)
    form.save()
    return redirect('cost-list')

এখানে ‘cost-list’ হচ্ছে cost_namagement/urls এর name=’cost-list’ থেকে পাওয়া URL এর নাম । 

সম্পূর্ণ ভিউ

def add_expense(request):

    if request.method == 'POST':
        form = ExpenseForm(request.POST)
        form.save()
        return redirect('cost-list')

    else:
        form = ExpenseForm
    return render(request, 'cost/add_expense.html', {'form': form})

বেশি বেশি খরচ করতে থাকুন আর আপনাার নিজর বানানো সফটওয়ার ব্যাবহার করে খরচের হিসাব রাখুন। আগামী পর্ব গুলোতে আমরা এই এপ্লিকেশনে আরো অনেক ফিচার যুক্ত করব।

আগের পোষ্ট    পরের পোষ্ট

Uncategorized

ফর্ম তৈরী -১ম পর্ব

by , on
March 4, 2017

বাংলায় জ্যাঙ্গো টিউটোরিয়াল সিরিজের মধ্যম ধাপে আপনাদর স্বাগতম। আমরা পূর্বের ধাপে একটি ব্লগ, ও একটি ব্যাক্তিগত হিসাব রাখার এপ তৈরী করেছিলাম। এই ধাপে আমরা ব্যাক্তিগত হিসাব রাখার এপ কে আরো সামনের দিকে এগিয়ে নেব। আমাদের প্রতিদিনের হিসাব রাখার জন্য আমাদেরকে এখন জ্যাঙ্গো এডমিন পাতায় যেতে হচ্ছে, যা ইউজারের জন্য বিরক্তিকর। home পেজ থেকেই কিভাবে নতুন হিসাব যোগ করা যায় তা আমরা এখন দেখব ।

পরিকল্পনা:

http://127.0.0.1:8000/cost/list/ পাতায় একটি বোতাম (Button) য়ুক্ত করব। যেটি চাপলে একটি ফর্ম আসবে। ফর্মটি পূরন করে নতুন হিসাব যুক্ত করব।

ফর্ম তৈরী:

আমরা হিসাব রাখার জন্য Expense মডেল তেরী করেছিলাম। এই মডেলের জন্যই একটি ফর্ম তৈরী করব। cost_management অ্যাপ এর মধ্যে forms.py তৈরী করি। নিচের কোড লিখে ফেলি

from django import forms
from .models import Expense


class ExpenseForm(forms.ModelForm):
    class Meta:
        model = Expense
        fields = '__all__'

প্রথমে আমাদেরকে জ্যাঙ্গো form (from django import forms)এবং Expense মডেল (from .models import Expense) import করি। ExpenseForm ই আমাদের ফর্ম ক্লাস। আমাদের বলে দিতে হবে যে আমাদের ক্লাসটি একটি মডেল ক্লাস। forms.ModelForm এই কাজটি করবে। ModelForm আমাদের কিছু জাদুকরি কাজ করে দেবে। মেটা ক্লাসের মধ্যে বলে দিতে হবে কোন মডেলের জন্য ফর্ম তেরী করবে। এবং ফর্মের ফিল্ড গুলো কি। ‘__all__’ অর্থ Expense মডেলে যত ফিল্ড আছে সব ফিল্ডের জন্য ফর্ম তৈরী করবে। fields = (‘amount’, ‘purpose’,’date’) এভাবেও লেখা যায়।

View তেরী

cost_management/views.py এর মধ্যে আমাদের তৈরী করা form ইমপোর্ট করি।

from .forms import ExpenseForm

অত:পর আমাদের ভিউ তেরী করি

 

def add_expense(request):
    form = ExpenseForm
    return render(request, 'cost/add_expense.html', {'form': form})

Expense ফর্ম তেরী করতে হলে ExpenseForm() কল করতে হবে এবং টেমপ্লেট এ পাঠাতে হবে। {‘form’: form} দ্বারা এই কাজ করা হয়েছে। template থেকে key ভ্যালু ‘form’ কে কল করলে আমাদের প্রত্যাশিত ফর্ম পেয়ে যাব। templates এর cost Directory এর মধ্যে add_expense.html টেমপ্লেট তরী করি।

Template তৈরী:

templates/cost/add_expense.html ফাইলে যোগ করি

{{ form }}

উল্লেখ্য, {{ form }} হচ্ছে render(request, ‘cost/add_expense.html’, {‘form’: form}) থেকে আসা form Key যা ExpenseForm ক্লাস থেকে এসেছে। এখন এই ভিউ কে প্রদর্শন করার জন্য একটি url তৈরী করি।

cost_management/urls এ একটি নতুন url যুক্ত করি

path('add-expense/', views.add_expense, name='add-expense'),

আমাদের urls.py এর চেহারা হবে

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

urlpatterns = [
    path('list/', views.my_expense, name='cost-list'),
    path('add/', views.add_expense, name='add-expense'),

]

(_ ও – ব্যাবহারে সতর্ক থাকুন)

ব্রাউজারে http://localhost:8000/cost/add/ প্রবেশ করান, নিচের মত চেহারা দেখতে পাবেন

amount purpose নামে দুটি ফিল্ড দেখতে পাচ্ছেন, যা আমাদের ExpenseForm ক্লাস এ ছিল। কিন্তু আমরা জানি html form তৈরী করতে হলে <form><input/></form> ইত্যাদি অনেক কিছু লিখতে হয়। আমরা তো শুধু {{ form }} লিখলাম। তাহলে এই ফর্ম আসল কিভাবে ? জ্যাঙ্গো form ModelForm সয়ংক্রিয়ভাবে আমাদেরকে এসব ট্যাগ তৈরী করে দিয়েছে। প্রমান চান? মাউসের ডান পাশে চেপে Inspect Elementকরুন, প্রমান পেয়ে যাবেন।

{{ form }} কে {{ form.as_p }} অথবা {{ form.as_table }} অথবা {{ form.as_ul }}এ পরিবর্তন করে টেমপ্লেট এর পরিবর্তন লক্ষ করুন। প্রতিবার Inspect Element করে html এর পরিবর্তন দেখুন।

base.html এর সাথে extend করে চেহারাকে আরো সুন্দর করে তুলি।

 

{% extends 'base.html' %}

{% block content %}

    {{ form.as_p }}

{% endblock %}

base.html এর content ব্লক এর মধ্যে ফর্ম এর কোড প্রবেশ করিয়েছি

এখন আমাদের খরচ তালিকার পেজে একটি বোতাম যুক্ত করি , যেখানে চাপলে এই ফর্ম পেজ আসবে।

<a class="btn btn-primary" href=" {% url 'add-expense' %}">Add New Expense</a>

এখানে add-expense হচ্ছে urls.py এর name= ‘add-expense’

উল্লেখ্যঃ মেনুতে খরচ তালিকা পেজের লিঙ্ক যোগ করতে base.html এর <ul></ul> এর মধ্যে যোগ করি

<li><a href="{% url 'cost-list' %}">Expense list</a></li>

লক্ষ করুন, আমাদের ফর্ম পেজে save করার জন্য কোন বোতাম নেই। আগামি পর্বে আমরা দেখব কিভাবে এই ফর্ম কে save করা যায় এবং নতুন খরচ যোগ করা যায়।

আগের পোষ্ট   পরের পোষ্ট