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

Uncategorized

প্রথম url, হ্যালো কেমন আছেন ?

by , on
September 10, 2018

আসসালামুয়ালাইকুম,
গত পর্বে আমরা “localhost:8000”url এ একটি ড্যামো সাইট দেখেছিলাম। এখন থেকে আমরা নিজেরা নতুন নতুন url তৈরী করব যা ব্রাউজারে প্রবেশ করালে চমৎকার কিছু কাজ আমাদের সামনে হাজির করবে। তো, প্রথমে ছোট্ট একটি url তৈরী করা যাক…

লক্ষ

বাংলায় জ্যাঙ্গো টিউটোরিয়াল সিরিজে আজকের পর্বে আমাদের লক্ষ, “localhost:8000/hi” ইউআরএল তৈরী করা যা ব্রাউজারে প্রবেশ করালে “Hello, how are you?” লেখাটি দেখাবে।

Url তৈরীঃ

প্রজেক্ট ডিরেক্টরির মধ্যে একই নামে আরেকটি ডিরেক্টরী আছে যেখানে urls.py ফাইল আছে। প্রজেক্টের সকল Url এই ফাইলের মধ্যে লেখা হয়। এখনে urlpatterns নামে একটি লিষ্ট আছে যার মধ্যে সকল url এর প্যাটার্ন তৈরী করা হয়।

path() ফাংশনের প্রথম প্যারামিটারে url এর গঠন দেয়া হয়। অর্থাৎ, ইউআরএল এর চেহারা যদি হয় ‘localhost:8000/hi’ তাহলে path ফাংশন লেখা হবে, path(‘hi’), যদি চেহারা  হয়

localhost:8000/home’ তাহলে path ফাংশন লেখা হবে, path(‘home’)

ইউআরএল টি ব্রাউজারে প্রবেশ করালে যে কাজ সংঘটিত হবে, সার্ভার যে কাজ করবে, ব্রাউজার যা প্রদর্শণ করবে, সবকিছু একটি ফাংশনের মধ্যে লেখা হয়, যাকে জ্যাঙ্গো এর ভাষায় view ফাংশন বলে। path() ফাংশনের ২য় প্যারামিটারে ওই ফাংশনকে call করা হয়। যেমন, আমরা যদি hello ফাংশনের মধ্যে কাজগুলো করি তাহলে তাহলে path ফাংশন লেখা হবে, path(‘hi’, hello) অর্থাৎ, ব্রাউজারে ‘localhost:8000/hi’ প্রবেশ করালে hello ফাংশনটি কল হবে।

View ফাংশন তৈরীঃ

from django.contrib import admin
from django.urls import path
from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello, how are you?")

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

ব্রাউজার, সর্ভারের কাছে একটি request পাঠাবে, যাকে বলে HttpRequest Hello ফাংশনটি সেই request কে তার প্যারামিটারের মধ্যে দিয়ে গ্রহন করবে। এখন সার্ভার, ব্রাউজারের পাঠানো HttpRequest কে প্রসেস করে, একটি স্ট্রিং কে HttpResponse হিসেবে ব্রাউজারে পাঠাবে। HttpResponse একটি ফাংশন, যাকে ইম্পোর্ট করতে হবে django.http মডিউল থেকে।

এখন সার্ভার রান থাকা অবস্থায় ব্রাউজারে লিখুন ‘localhost:8000/hi’ এবং আপনার প্রত্যাশিত ফলাফল দেখে নিন।

আমরা সহজভাবে বোঝার জন্য view ফাংশন এবং url একই ফাইলে লিখেছি, কিন্তু এটা অনুচিত। ভিন্ন ধরণের কোড আলাদা আলাদা ফাইলে লেখা উত্তম।
তাই আমরা view ফাংশনটিকে( hello() ) views.py নামে ভিন্ন একটি ফাইলে নিখে ফেলি। যেখানে urls.py আছে, একই ডিরেক্টরিতে views.py নামে ফাইল তৈরী করি।

banglaidj/banglaidj/views.py

from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello, how are you?")

banglaidj/banglaidj/urls.py

from django.contrib import admin
from django.urls import path
from .views import hello  # import view function from views.py

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

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

Uncategorized

virtualenvwrapper কি এবং কেন ব্যবহার করবেন ?

by , on
August 13, 2018

আসসালামুয়ালাইকুম,
আশা করি আপনারা জ্যাঙ্গো বেশ ভালোই শিখে ফেলেছেন, এবং মজায় মজায় কিছু প্রজেক্ট ও করে ফেলেছেন।  

virtualenvwrapper কি ?


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

ইন্সটল করুন


আপনার PIP3  ইন্সটল করা না থাকলে করে ফেলুন

sudo apt-get install python3-pip

একইসাথে virtualenvwrapper ও ইন্সটল করুন

sudo pip3 install virtualenvwrapper

এখন shell startup ফাইলে ( .bashrc ) কিছু কমান্ড লিখে দিতে হবে । .bashrc ফাইলটি টার্মিনাল  এডিটরে খুলুন। ( আমি nano এডিটর ব্যাবহার করব

nano  ~/.bashrc

আপনার টার্মিনালে .bashrc ফাইলটি খুলবে। একেবারে শেষে নিচের লাইনগুলো যোগ করুন

export WORKON_HOME="$HOME/.virtualenvs"
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /usr/local/bin/virtualenvwrapper.sh

nano এডিটরে ফাইল সেভ করে বের হয়ে আসতে  Ctrl + X  অতঃপর Y চাপুন । 
.bashrc
ফাইলটি রিলোড লিতে লিখুন 

source ~/.bashrc

তৃতীয় লাইনে virtualenvwrapper.sh এর লোকেশন যুক্ত করা হয়েছে। অনেকের এই লাইনে ইরর দেখাতেও পারে ( সম্ভাবনা খুব কম ) । যদি ফাইলটি পাচ্ছে না এমন কোন ইরর দেখায় তাহলে আপনার virtualenvwrapper.sh কোন লোকেশনে আছে দেখতে লিখুন

which virtualenvwrapper.sh

ব্যাস, আপনার virtualenvwrapper ইন্সটল শেষ, এখন মনের সুখে ব্যাবহার করুন। 

ব্যাবহার

virtual environment তৈরী করতে টার্মিনালে লিখুন,

mkvirtualenv testenv1

testenv1 নামে একটি virtualenvironment তৈরী হবে যটি থাকবে আপনার হোম এর  .virtualenvs ডিরেক্টরীতে। 
আপনার তৈরী করা ভার্চুয়ার এনভাইরনমেন্ট গুলো দেখতে লিখুন 

workon

কোন নির্দিষ্ট এনভাইরনমেন্ট একটিভ করতে লিখুন  workon your_env_name. যেমন,

workon testenv1

deactivate করতে লিখুন 

deactivate

কোন একটি Environment মুছে ফেলতে লিখুন rmvirtualenv env_name

rmvirtualenv testenv1

 

Uncategorized

Create Custom Template Tags in Django – Bangla

by
, on
August 1, 2018

এই টিউটোরিয়ালে যেসব বিষয়গুলো থাকছে-
  •  ব্লগের মোট পোস্ট সংখ্যা দেখানোর জন্য custom template tag ।
  • ব্লগের  latest post গুলো দেখানোর জন্য custom template tag।

“বেশি করে আলু খান, ভাতের উপর চাপ কমান।” এই টাইপ একটা স্লােগান বাংলাদেশে কোন একসময় খুব প্রচারিত হতো।  অর্থাৎ একটার উপর থেকে চাপ কমানোর জন্য আরেকটার বিকল্প ব্যবহার।

জ্যাঙ্গোতে আমরা সাধারণত বিভিন্ন কুয়েরী চালিয়ে কোন ডাটাকে views.py থেকে কনটেক্সট ডাটা হিসেবে টেমপ্লেটে পাঠাই। সেক্ষত্রে আমাদের অ্যাপসের ফাংশানালিটি যদি বেশি হয়, তবে views.py ফাইলে কোডের লাইন সংখ্যা বেড়ে যায়।

views.py ফাইলের উপর থেকে চাপ কমানোর জন্য ছোটখাটো কিছু কুয়েরী বা অপারেশন আমরা custom template tags এর মাধ্যমে তৈরি করার চেষ্টা করবো।

জ্যাঙ্গো কাস্টম টেমপ্লেট ট্যাগ তৈরি করার জন্য  simple_tags এবং inclusion_tags নামে দুইটা ফাংশনালিটি প্রদান করে।

  • simple_tags: string বা কাঙ্খিত রেজাল্ট return করে।
  • inclusion_tags: render template রির্টান করে।

এখন মনে করি আমাদের blog নামে একটা এপস আছে যেখানে Post নামে একটি model ক্লাস রয়েছে। আমরা চাই আমাদের blog এ যতগুলো পোস্ট আছে তা কাউন্ট করে টেমপ্লেটে প্রদর্শন করতে। এর জন্য আমরা total_post নামে একটা custom template tag লিখবো।

এই কাজটা করার জন্য blog ডিরেক্টরীতে templatetags নামে একটা নতুন ফোল্ডার তৈরি করি। এই ফোল্ডারের ভিতের __init__.py এবং blog_tags.py নামে দুটি নতুন ফাইল তৈরি করি-

templatetags/
   __init__.py
   blog_tags.py

এখন blog_tags.py ফাইলটিকে ওপেন করে নিচের কোডটুকু লিখা যাক:

from django import template
from blog.models import Post
register = template.Library()
@register.simple_tag
def total_post():
    return Post.objects.count()
  • প্রথমেই django এর template মডিউলকে import করা হয়েছে।
  • সবগুলো পোস্ট কাউন্ট করার জন্য model  থেকে Post মডেল ক্লাস import করা হয়েছে।
  • কাষ্টম টেমপ্লেট ট্যাগটিকে জ্যাঙ্গোর টেমপ্লেট লাইব্ররীতে যুক্ত করার জন্য register নামে template.Library() এর instance তৈরি করা হয়েছে।
  • তারপর total_post() নামে একটি মেথড তৈরি করা হয়েছে এবং এটাকে simple tag হিসেবে বিবেচনা করার জন্য @register.simple_tag ডেকোরেটর ব্যবহার করা হয়েছে।

মেথডের নামটিই কাস্টম ট্যাগ এর নাম হিসেবে ব্যবহার করা হবে। ট্যাগের অন্য কোন নাম দিতে চাইলে simple tag ডেকোরেটরের ভিতরে name প্যারামিটার ব্যবহার করে ট্যাগের ভিন্ন কোন নাম দেওয়া যাবে। যেমন- @register.simple_tag(name=’my_tag’)

  • তারপর Post মডেলে যতগুলো পোস্ট অবজেক্ট আছে সবগুলো গণনা করে return করা হয়েছে।

এরপর কাজ হবে custom tags এর  ফাইলটা অর্থাৎ blog_tags.py কে base template অথবা যে template এর মধ্যে আমরা কাস্টম ট্যাগ ব্যবহার করবো সেখানে  load করা অর্থাৎ টেমপ্লেটের শুরুতেই –

{% load blog_tags %}

এই অংশটুকু যোগ করতে হবে। তারপর template এর যেখানে আমরা total post এর সংখ্যা দেখাতে চাই সেখানে –

{% total_post %}

এই অংশটুকু যোগ করলেই মোট পোস্টর সংখ্যাটা দেখাবে।

Custom Tag For Latest Post:

এখন আমরা আরেকটি কাস্টম ট্যাগ বানাবো যার মাধ্যমে যেন আমরা  latest post  খুঁজে বের করতে পারি। এটা করার জন্য আমরা inclusion_tag ব্যবহার করবো (simple_tag ব্যবহার করে নিজেরা চেষ্টা করে দেখতে পারেন)।

blog_tags.py ফাইলটা edit করা যাক-

from django import template
from blog.models import Post

register = template.Library()

@register.simple_tag
def total_post():
    return Post.objects.count()

@register.inclusion_tag('blog/post/latest_posts.html')
def show_latest_posts(count=5):
    latest_posts = Post.objects.order_by('-publish')[:count]
    return {'latest_posts':latest_posts}
    • show_latest_posts নামে নতুন আরেকটা মেথড ব্যবহার করা হয়েছে। যেখানে count  নামে একটা প্যারামিটার নেওয়া হয়েছে ডিফল্টভাবে যার ভ্যালু 5   । যখন show_latest_posts ট্যাগটি টেমপ্লেটে ব্যবহার করা হবে তখন কতগুলো latest post দেখাতে চাই সেটা নির্ধারণ করে দেওয়ার জন্য count প্যারামিটারটি ব্যবহার করা হয়েছে।
    • @register.inclusion_tag ডেকোরেটরের মধ্যে নতুন একটা টেমপ্লেট latest_posts.html উল্লেখ করা হয়েছে। এর ফলে {% show_latest_post %} ট্যাগটি latest_posts.html টেমপ্লটেকে  কাঙ্খিত টেমপ্লটে(যেই template এ এই ট্যাগ ব্যবহার করা হবে) render করবে।
    • Post মডেল থেকে কুয়েরী চালিয়ে latest publish date অনুযায়ী সাজিয়ে count এর সমান সংখ্যক পোস্টকে latest_posts ভ্যারিয়বলে রাখা হয়েছে।
    • মেথডটি dictionary টাইপ ডাটা রিটার্ন করেছে (context ডাটা হিসেবে) যা আমরা render কৃত template (latest_posts.html) এ ব্যবহার করতে পারবো।

     

এখন latest_posts.html টেমপ্লটেকে edit করা  যাক:

<ul>
  {% for post in latest_posts  %}     
  <li>
     <a href="{{post.get_absolute_url}}">{{post.title}}</a>
  </li>
  {% endfor %}
</ul>

এখানে show_latest_posts মেথড যে context ডাটা(latest_posts) রির্টান করেছিলো, সেটা ব্যবহার করে unordered list এর মধ্যে for লুপ এর মাধ্যমে প্রতিটা পোস্টের title প্রদর্শন করা হয়েছে, সাথে প্রতিটা টাইটেলের সাথে তাদের details এর লিঙ্ক যুক্ত করে দেওয়া হয়েছে।

এখন আমরা যেকোন template এর মধ্যে যে স্থানে {% show_latest_posts  %} ট্যাগটি ব্যবহার করবো, সেখানে latest_posts.html  টেমপ্লটেটি render হবে অর্থাৎ সেখানে latest post গুলো unordered list আকারে দেখাবে। latest post এর সংখ্যা নির্ধারণ করে দেওয়ার জন্য show_latest_posts ট্যাগটির পরে কাঙ্খিত সংখ্যা উল্লেখ করতে হবে।

যেমন- যদি latest চারটি পোস্ট দেখাতে চাই তবে-

{% show_latest_posts  4  %}

আশা করি সবাই বুঝে গেছেন কিভাবে কাস্টম ট্যাগ ব্যবহার করে views.py এর চাপ কিছুটা কমাতে পারি।

ধন্যবাদ সাথে থাকার জন্য…. 🙂

[If you find any inconsistency, please let me know]

Uncategorized

Django-taggit in Bangla (Add tags in your posts)

by
, on
July 30, 2018

 

এই টিউটোরিয়ালে যে বিষয়গুলো থাকছে-

  • Adding tags in your post
  • Find posts by tags
  • Display similar posts

জ্যাঙ্গোতে ট্যাগ যোগ করার জন্য  django-taggit  নামক একটা থার্ডপার্টি এপস ব্যবহার করবো। এর জন্য প্রথমেই  django-taggit ইন্সটল করতে হবে-

pip install django-taggit

 

ইন্সটল প্রক্রিয়া সম্পন্ন হওয়ার পর  প্রজেক্টের (blog) settings.py ফাইলে যেয়ে INSTALLED_APPS এর লিস্টে ‘taggit‘ যোগ করে দিতে হবে।

Adding tags in your post:

আমরা প্রতিটা পোস্টের মধ্যে ট্যাগ যোগ করতে চাই। ধরি, blog নামক এপসের models.py ফাইলে পোস্ট  এর জন্য  Post নামে একটা মডেল ক্লাস রয়েছে। এখন এই Post মডেল ক্লাসটির মধ্যেই আমরা প্রতিটা পোস্ট অবজেক্টের জন্য ট্যাগ যোগ করবো-

class Post(models.Model):
    tags = TaggableManager()
    # others field
  • এখানে TaggableManager() প্রতিটা  অবেজেক্টের জন্য (এখানে পোস্ট অবজেক্ট)  ট্যাগ add,remove, retrieve অপারেশন সম্পন্ন করে থাকে।

এর পর makemigrations এবং পরে migrate কমান্ডের মাধ্যমে  django-taggit এর জন্য ডাটাবেস টেবিল তৈরি করতে হবে।

taggit এর ডাটাবেস টেবিলের রিলেশনটা এরকম হবে-

 

taggit_tag Table:

  • taggit_tag টেবিলে এর মধ্যে প্রতিটা ট্যাগের নাম থাকবে। অর্থাৎ প্রতিটা ট্যাগই হচ্ছে একেকটা অবজেক্ট।

taggit_taggeditem Table(Look Up Table):

  •  object_id  তে পােস্ট অবজেক্টর id থাকবে।
  • উক্ত পোস্ট অবজেক্টটির জন্য   নির্দিষ্ট tag_id থাকবে যা taggit_tag টেবিলের id কে নির্দেশ করবে আর প্রতিটা id এর জন্য taggit_tag টেবিলে অনেকগুলো ট্যাগের অবজেক্ট (tags) থাকবে।
  •  content_type_id টা হচ্ছে প্রতিটা পোস্ট অবজেক্টের জন্য ভিন্ন ভিন্ন id যা জ্যাঙ্গো অটোমেটিক্যালি তৈরি করে থাকে।

 

এখন python manage.py shell কমান্ডের  মাধ্যমে পাইথনের শেল টার্মিনাল ওপেন করি। তারপর Post মডেলের ডাটাবেস থেকে কুয়েরি করে যেকোন একটা পোস্ট অবজেক্টকে একসেস করি-

>>>from blog.models import Post
>>>post = Post.objects.get(id=2)

আমরা ডাটাবেস টেবিল থেকে id =2 নং পোস্ট অবজেক্টটি কুয়েরী করে post নামক ভ্যারিয়বলের মধ্যে রেখে দিলাম। এখন কাজ হবে এই post এর সাথে ট্যাগ যোগ করা-

>>post.tags.add('python', 'django')

আমরা python এবং django নামে দুইটা ট্যাগ, পোস্ট অবজেক্টির সাথে যুক্ত করে দিলাম।

এখন ডাটাবেস টেবিল দেখতে কেমন হবে  দেখা যাক-

taggit_tag
id name slug
1 python python
2 django django
taggit_taggeditem
id object_id content_type_id tag_id
1 2 9 1
2 2 9 2

অর্থাৎ content_type  9, যার  অবজেক্ট id 2, তে tag_id  1 এবং 2 দুটি ট্যাগ যুক্ত আছে।

এখন আমরা চাই আমাদের ট্যাগগুলো  list.html টেমপ্লেটের প্রতিটা পোস্টের নিচে দেখাবে।

সেজন্য list.html টেমপ্লেটের  পোস্টের টাইটেলের নিচে এটা যুক্ত করি-

 <p> Tags: {{ post.tags.all|join:", " }} </p>

এখানে post.tags.all|join  প্রতিটা পোস্টের জন্য সবগুলো ট্যাগকে কমা (,) দিয়ে জয়েন্ট করে এক লাইনে দেখানোর জন্য ব্যবহার করা হয়েছে।

Find posts by tags:

এখন আমরা  প্রতিটা ট্যাগের সাথে লিঙ্ক যুক্ত করতে চাই, যেন যেকোন ট্যাগের মধ্যে ক্লিক করলে এই ট্যাগ রিলেটেড  সবগুলো পোস্টের লিস্ট দেখা যায়।

এই কাজটা করার জন্য যেসব কাজ করতে হবে-

  1. প্রতিটা ট্যাগে যখন ক্লিক করবো তখন সেই ট্যাগের slug সংগ্রহ করা। এর জন্য আলাদা URL লিখতে হবে  slug এর ডাটা নেয়ার জন্য।
  2. সংগ্রহকৃত slug টা কোন কোন অবজেক্টের মধ্যে আছে তা views.py ফাইলের list_view  ফাশংনের মধ্যে কুয়েরী চালিয়ে বের করা।
  3. প্রাপ্ত রেজাল্টগুলো পুনরায় list.html টেমপ্লেটে render করা।

উপরের স্টেপগুলো এবার এক এক করে ইমপ্লিমেন্ট করা যাক। এর জন্য আমরা প্রথমে এটা ধরে নিই যে, views.py  ফাইলে আমাদের post_list নামক একটা মেথড রয়েছে যার কাজ হচ্ছে পোস্ট অবজেক্টগুলোর লিস্ট render করে টেমপ্লেটে পাঠানো।

এখন blog নামক অ্যাপস এর urls.py ফাইলে urlpatterns=[] এর ভিতরে নতুন একটি URL তৈরি করি-

urlpatterns=[

    path('tag/<slug:tag_slug>/',views.post_list, name='post_list_by_tag'),

    # others url ....

]

এবার views.py  edit করা যাক-

def post_list(request,tag_slug=None):
    posts = Post.objects.all()
    tag = None

    if tag_slug:
        tag = get_object_or_404(Tag,slug=tag_slug)
        posts = posts.filter(tags__in=[tag])
    return render(request,'blog/post/list.html',{'posts':posts,'tag':tag})
  • প্যারামিটার হিসেবে tag_slug=None নেওয়া হয়েছে। কারণ সাধারণভাবে যখন কোন ট্যাগ থাকবে না, তখন এটা None।
  • posts নামক ভ্যারিয়বলের মধ্যে Post  মডেলের ডাটাবেসে কুয়েরী চালিয়ে সকল পোস্ট অবজেক্টের একটা লিস্ট তৈরি করা হয়েছে।
  • tag নামক ভ্যারিয়বল শুরুতে None
  • যদি  tag_slug থাকে, তবে tag ভ্যারিয়েবলের  ভ্যালু সেই tag_slug এর অবজেক্ট হবে।
  • tag_slug এর ভ্যালু এখানে একটা string  ।  ইতিপূর্বে আমরা দেখেছি যে, tags গুলো taggit_tag (Tag)  এর অবজেক্ট । tag_slug এর ভ্যালু (string) এর মাধ্যমে Tag মডেল থেকে  উক্ত ট্যাগের অবজেক্টটি কুয়েরী করা হয়েছে।
  • যে পোস্ট অবজেক্টগুলোর tags ফিল্ডের মধ্যে ঐ tag  অবজেক্টগুলো আছে তা filter এর মাধ্যমে বের করা হয়েছে।
  • সবশেষে posts এবং tag কনটেক্স ডাটা হিসেবে পাঠানো হয়েছে।

এখন list.html টেমপ্লেটের প্রতিটা ট্যাগ এর মধ্যে লিঙ্ক যুক্ত করতে হবে যা tag.slug কে URL এর মাধ্যমে post_list view তে প্যারামিটার হিসেবে পাঠিয়ে দিবে-

{% if tag %}
  Tags:
  {% for tag in post.tags.all %}
  <a href="{% url 'blog:post_list_by_tag' tag.slug %}">{{tag.name}}</a>
  {% if not forloop.last %}, {% endif %}
  {% endfor %}
{% endif %}

এখন যেকোন পোস্টের যেকােন tags এ ক্লিক করলে সেই ট্যাগ রিলেটেড সবগুলো পোস্টের লিস্ট দেখা যাবে।

Display similar posts:

এখন  যদি এমন চাই ,  যে পােস্টটির details পড়া হবে, সেই পোস্টের ট্যাগ রিলেটেড  অন্যান্য পােস্টগুলোও  (similar post)  সাজেস্ট করবে, তাহলে views.py ফাইলের post_detail মেথডের মধ্যে আমরা কিছু পরিবর্তন করে কাজটা খুব সহজেই করতে পারি-

def post_detail(request):
    post = get_object_or_404(Post,**kwargs)

    #Similar Posts
    post_tags_ids = post.tags.values_list('id',flat=True)
    similar_posts = Post.objects.filter(tags__in=post_tags_ids).exclude(id=post.id)
    similar_posts = similar_posts.annotate(same_tags=Count('tags')).order_by('-same_tags')[:4]
    
    return render(request,'blog/post/detail.html',{'post':post,'similar_posts':similar_posts})
  • যে পোস্ট অবজেক্টটির details পড়তে চাই, সেই পোস্ট অবজেক্টটি Post মডেল থেকে বিভিন্ন কিওয়ার্ড আর্গুমেন্ট  এর মাধ্যমে get_object_or_404 মেথড ব্যবহার করে কুয়েরী করা হয়েছে।
  • তারপর সেই post অবজেক্টির যতগুলো tags আছে, সবগুলোর id নিয়ে একটি লিস্ট তৈরি করা হয়েছে।
  • তারপর এই post_tags_ids গুলো নিয়ে Post মডেলে কুয়েরী করে যতগুলো পোস্ট অবজেক্টের মধ্যে এই tag id গুলো রয়েছে সবগুলোর একটা লিস্ট similar_post ভ্যারিয়েবলের মধ্যে রাখা হয়েছে। বর্তমান পোস্ট অবজেক্টটি বাদ দেওয়ার জন্য exclude ব্যবহার করা হয়েছে।
  • এরপর annotate() মেথডের মাধ্যমে  প্রতিটা similar_post অবজেক্টের জন্য same_tags নামক একটা অ্যাট্রিবিউট তৈরি করা হয়েছে, যা প্রতিটা similar post এর tags গুলোকে Count() মেথডের মাধ্যমে  সর্বাধিক মিলের ভিত্তিতে গণনা করে একটা কুয়েরী সেট প্রদান করে।
  • .order_by() মেথডের মাধ্যমে similar_tags এর ভ্যালু বড় থেকে ছোট এর ভিত্তেত সাজানো হয়েছে এবং [:4] এর মাধ্যমে সর্বাধিক মিলের 4 টা  similar post কে রাখা হয়েছে।
  • এর পর similar_post কে কনটেক্স ডাটা আকারে টেমপ্লেটর জন্য  পাঠানো হয়েছে।

এতটুকু শেষ করার পর ইচ্ছে মতো টেমপ্লেটর details.html এর যেকোন  জায়গাতে আমরা similar post গুলো দেখাতে পারি।

ধন্যবাদ সাথে থাকার জন্য..।

(If you have any question, please feel free to ask)

[If you find any inconsistency, please let me know]

Uncategorized

জ্যাঙ্গো কন্টেন্ট টাইপ এবং জেনেরিক রিলেশন (Django Content Types And Generic Relation)

by
, on
July 22, 2018

কখনো কখনো Foreign Key ফিল্ডে আমাদের ডায়নামিক ভাবে মডেল যুক্ত করার দরকার হয়। যদিও সাধারণ ভাবে একটিForeignKey ফিল্ডে একাধিক মডেল রাখা সম্ভব না (যেখান থেকে আমরা ইচ্ছামত যেকোন একটা মডেল সিলেক্ট করতে পারি)! এক্ষেত্রে আমরা দুইভাবে কাজ করতে পারি, একাধিক Nullable ফরেন কী ফিল্ড তৈরি করে অথবা জেনেরিক রিলেশন ব্যবহার করে।

প্রথমে দেখব একাধিক ফরেন কী ফিল্ড ব্যবহার করে অপারেশনগুলো কিভাবে করা যায়। ধরা যাক আমাদের কাছে Post , Comment এবং Review নামে তিনটি মডেল আছেঃ

# পোস্ট মডেল
class Post(models.Model):
    text = models.TextField()

# কমেন্ট মডেল
class Comment(models.Model):
    text = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')

# রিভিউ মডেল
class Review(models.Model):
    text = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.SET_NULL, null=True, blank=True, related_name='reviews')
    comment = models.ForeignKey(Comment, on_delete=models.SET_NULL, null=True, blank=True, related_name='reviews')

 

তো আমরা নিচের মত অপারেশন চালাতে পারিঃ

# 1.1 একটি পোস্ট তৈরি করি
post_object = Post.objects.create(text='new post')

# 1.2 পোস্ট এর জন্য একটি রিভিউ তৈরি করি। ( রিভিউ মডেল থেকে! ) 
review_object_for_post = Review.objects.create(text='review for awesome post', post=post_object)

# 1.3 পোস্ট এর জন্য আরেকটি রিভিউ তৈরি করি। (পোস্ট অবজেক্ট থেকে!) 
review_object_for_post_reverse = post_object.reviews.create(text='another review for awesome post' )

# 1.4 নির্দিষ্ট একটি পোস্টের সকল রিভিউ ফিল্টার করি। (রিভিউ মডেল থেকে) 
all_reviews_for_specific_post = Review.objects.filter(post=post_object)

# 1.5 নির্দিষ্ট একটি পোস্টের সকল রিভিউ ফিল্টার করি। (পোস্ট অবজেক্ট থেকে) 
all_reviews_for_specific_post_reverse = post_object.reviews.all()

# 1.6 নির্দিষ্ট একটা রিভিউ অবজেক্ট থেকে সেটার পোস্ট অব্জেক্ট বের করি
post_object_of_specific_review = review_object_for_post.post

 

একই স্টাইলে আমরা কমেন্টের অপারেশন গুলোও করতে পারি।

# 2.1 একটি কমেন্ট তৈরি করি 
comment_object = Comment.objects.create(text='new comment', post=post_object)

# 2.2 কমেন্ট এর জন্য একটি রিভিউ তৈরি করি। ( রিভিউ মডেল থেকে! ) 
review_object_for_comment = Review.objects.create(text='review for awesome Comment', comment=comment_object)

# 2.3 কমেন্ট এর জন্য একটি রিভিউ তৈরি করি। (কমেন্ট অবজেক্ট থেকে!) 
review_object_for_comment_reverse = comment_object.reviews.create(text='another review for awesome Comment' )

# 2.4 নির্দিষ্ট একটি কমেন্টের সকল রিভিউ ফিল্টার করি (রিভিউ মডেল থেকে) 
all_reviews_for_specific_comment = Review.objects.filter(comment=comment_object)

# 2.5 নির্দিষ্ট একটি কমেন্টের সকল রিভিউ ফিল্টার করি (কমেন্ট অবজেক্ট থেকে) 
all_reviews_for_specific_comment_reverse = comment_object.reviews.all()

# 2.6 নির্দিষ্ট একটা রিভিউ অবজেক্ট থেকে সেটার কমেন্ট অব্জেক্ট বের করি
comment_object_of_specific_review = review_object_for_comment.comment

# আরো অনেক ধরনের কুয়েরি করতে পারি, সেগুলো না হয় আরেকদিন দেখব!

 

উপরের 1.6 এবং 2.6 নং কুয়েরিতে একটি সমস্যা আছে, একটা রিভিউ যেহেতু পোস্টেরও হতে পারে আবার কমেন্টেরও হতে পারে তাই আগে থেকে জানা না থাকলে এটা বের করা ঝামেলা যে কোনো একটা রিভিউ আসলে কার! Post এর নাকি Comment এর!?
সেক্ষেত্রে আমাদেরকে আগে চেক করে বের করতে হবে রিভিউটি কার, তারপর অবজেক্টটি গেট করতে পারব!
অনেকটা এভাবেঃ

if another_review.post:
    review_for = another_review.post

elif another_review.comment:
    review_for = another_review.comment

else:
    review_for = None

# যদি আরো কোন ফরেন কী ফিল্ড থাকে তাহলে সেগুলোও এভাবে চেক করতে হবে।

 

এই সমস্যা সহজে হ্যান্ডেল করতে পারি রিভিউতে একটি আলাদা ক্যারেক্টার ফিল্ড রেখে! যেখানে আমরা মডেলের নাম লিখে রাখব অর্থাৎ Post অথবা Comment ! পরে সেই ফিল্ড চেক করে দ্রুত বের করতে পারব এটা কার রিভিউ!

যাই হোক, ফরেন কী হিসেবে ডায়নামিক ভাবে (মাল্টিপল মডেল থেকে যেকোনো) মডেল সিলেক্ট করে দেয়ার জন্য ডিফল্ট ভাবে জ্যাঙ্গোতে সুন্দর একটা সিস্টেম আছে! ‘জেনেরিক রিলেশনস ‘ (Generic Relations )! এটা ব্যবহার করার জন্য আমাদেরকে নির্ভর করতে হবে জ্যাঙ্গোর বিল্টিন এপ ‘কন্টেন্ট টাইপ্স’ (ContentTypes) এর উপর! সংক্ষেপে, ContentTypes এপটি একটি জ্যঙ্গো প্রোজেক্টের সকল মডেলের আইডিগুলো সেভ করে রাখে! আপাতত এতটুকু জানাই আমাদের জন্য যথেষ্ট 😛 ! এখন দেখব উপরের কাজটা কনটেন্ট টাইপ আর জেনেরিক রিলেশন দিয়ে কিভাবে করে ফেলা যায়!

প্রথমেই আমদের তিনটা মডেল তৈরি করে নেই!

# এই তিনটি ক্লাস ইম্পোর্ট করতে হবে 
from django.contrib.contenttypes.fields import GenericForeignKey 
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.models import ContentType


# রিভিউ মডেল, জেনেরিক রিলেশনের সাথে! 
class Review(models.Model):
    text = models.TextField()

    # নিচের তিনটি ফিল্ড আবশ্যক, এভাবেই লেখা যাবে
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()

# পোস্ট মডেল, রিভার্স কুয়েরি করার জন্য রিভিউ এর সাথে জেনেরিক রিলেশন করা। 
class Post(models.Model):
    text = models.TextField() 
    reviews = GenericRelation(Review, related_query_name='posts')


# কমেন্ট মডেল, রিভার্স কুয়েরি করার জন্য রিভিউ এর সাথে জেনেরিক রিলেশন করা। 
class Comment(models.Model):
    text = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    reviews = GenericRelation(Review, related_query_name=' comments')

 

এক্ষেত্রে সুবিধা হল, এর পর আরও নতুন যত মডেলের সাথেই আমি রিভিউ এর রিলেশন করতে চাইনা কেন আমাকে রিভিউ মডেলে চেঞ্জ করতে হবেনা, জাস্ট নতুন মডেলের মধ্যে reviews = GenericRelation(Review) দিয়ে দিলেই কাজ শেষ!

# 3.1 পোস্ট এবং কমেন্ট অবজেক্ট তৈরি করি 
post_object = Post.objects.create(text='new post')
comment_object = Comment.objects.create(text='new comment ', post=post_object)

# 3.2 রিভিউ মডেল থেকে নির্দিষ্ট পোস্ট এবং কমেন্টের জন্য রিভিউ তৈরি করি
review_object_for_post = Review.objects.create(text='awesome post', content_object=post_object)
review_object_for_comment = Review.objects.create(text='awesome comment', content_object=comment_object)

# নির্দিষ্ট পোস্ট অবজেক্ট এবং কমেন্ট অবজেক্ট থেকে সেগুলোর রিভিউ তৈরি করি
review_object_for_post_reverse = post_object.reviews.create(text='awesome post')
review_object_for_comment_reverse = post_object.reviews.create(text='awesome comment')

# 3.3 রিভিউ মডেল থেকে নির্দিষ্ট পোস্ট অবজেক্ট এবং কমেন্ট অবজেক্ট এর সকল রিভিউ ফিল্টার করি
all_reviews_for_specific_post = Review.objects.filter(posts=post_object)
all_reviews_for_specific_comment = Review.objects.filter(comments=comment_object)

# 3.4 নির্দিষ্ট পোস্ট অবজেক্ট এবং কমেন্ট অবজেক্ট থেকে সেগুলোর সকল রিভিউ ফিল্টার করি
all_reviews_for_specific_post_reverse = post_object.reviews.all()
all_reviews_for_specific_comment_reverse = comment_object.reviews.all()

# 3.5 নির্দিষ্ট রিভিউ অবজেক্ট থেকে সেটার পোস্ট 'বা' কমেন্ট অবজেক্ট বের করি
post_or_comment_object_for_specific_review = review_object_for_post.content_type
post_or_comment_object_for_specific_review = review_object_for_comment.content_type

 

—————————————-
লেখাটি নিজের জন্যই নোট হিসেবে রাখলাম, পরে আরো আপডেট করার ইচ্ছা আছে ইনশাল্লাহ …

Uncategorized

Learn Python with complete web development project

by , on
July 9, 2018

Description

Python is now the best programming language to learn in 2018. Python is very easy to learn and you will find it in web application development, machine learning, data science, desktop app, hardware programming etc.

Khidmah It, leading software training company in Dhaka,  is offering  web application development course with complete project. Are you beginner in programming ? no problem, if you have passion, dedication, you can learn from scratch .

What we learn?

  • Python from Scratch to Advance
  • Django Basic to Mid level
  • Linux, Git
  • Complete real life project following Agile Methodology.
  • problem solving
  • Basic Algorithm

About Course:

Time: Friday, Saturday 3 P.M

Total class: 32

Duration: 4 month ( 96 hours)

Free Class: 3 August 2018

Main class: 4 August 2018

Course Fee: 10,000 tk

Address: O-23, Muslim sweets goli, Nur-Jahan road, Mohammadpur, Dhaka

** To enroll this course, Fill up registration form and join to our free class on 3 August

Course curriculum:

  • Getting Started with Python3
  • Data structure
  • OOP -Object oriented Programing with python
  • Exception Handling
  • File Handling
  • Flask framework basic
  • Getting started with Django2
  • Basic Django ( models, views, templetes, urls, Forms)
  • Django Queryset
  • Class Based View
  • Django Rest API
  • Working with Postgresql Database
  • Version control with Git
  • Basic Concept of Freelancing and how to apply for job in freelance marketplace.

Offers:

  1. Skilled programmer ( any language) who attended any programming contest (online/offline) and got good score, will get up to 30% discount as his skill. 
  2. For Hafiz ( Quran) , completed Dawraye Hadith ( maolana ) and pass 40 day’s chilla in Tablig jamat,  20% discount in course fee.

 Contact

Contact: Facebook Page Facebook Group, Banglai-django Facebook group

Phone: 01715251562, 01753163092

Note:

2. Women should maintain hizab as  Islamic shariah

3. We have no lab setup. You have to bring your own laptop with Linux OS.

4. If someone fail to attend some class, backup class will available.

5. Our class assistant will support you to solve any problem.

Uncategorized

UVA 414 – Machined Surfaces

by
, on
May 16, 2018

[pdf-embedder url=”http://www.banglai-django.com/wp-content/uploads/2018/05/p414.pdf”]

প্রথমে আমরা প্রব্লেম টি ভালভাবে বুঝার চেষ্টা করি
#এখানে বলছে যে একটা ইমেজ এর ২ টা Surface একটা বাম Surface এবং আরেকটা ডান Surface.
#প্রত্যেক Surface এর শুরু এবং শেষ হবে ‘X’ দিয়ে
#যেকোনো সংখ্যক space থাকতে পারে তবে “There will never be more than a single blank region in any row” মানে হচ্ছে ‘XX—–XXX ‘ হতে পারে but ‘XXX—XXX—XXX ‘ এরকম কিছু হবেনা
# column সংখ্যা ২৫
# row অনেক গুলো হতে পারে
#বাম Surface থেকে ডান Surface এ একেক ঘর করে সামনে আগাতে থাকবে যতক্ষণ পর্যন্ত যেকোনো একটা row এর বাম Surface এবং ডান Surface এর মাঝে কোনো ফাঁকা থাকবেনা
আমাদেরকে বের করতে হবে যে কন্ডিশন false হবার পরে ইমেজ এ টোটাল কত গুলো স্পেস আছে

আমরা python3 দিয়ে সল্ভ করবো
প্রথমে একটা ফাঁকা লিস্ট নিবো এর পরে একটা ইন্টিজার ভ্যালু ইনপুট নিয়ে চেক করবো যে এটা ০ কিনা যদি ০ হয় তাহলে break করে দিবো আর ০ না হলে এর range পর্যন্ত string ইনপুট নিবো প্রতিবার স্ট্রিং ইনপুট নিবার পরে এর ভিতরে কত গুলো ফাঁকা স্পেস আছে তা count করে ফেলবো এবং এই count এর ভ্যালু লিস্ট এর মধ্যে append করবো এর পরে আমরা লিস্ট কে সর্ট করবো লিস্ট সর্ট করার পরে আমরা লুপ চালায়ে লিস্ট এর প্রতিটি আইটেম কে লিস্ট এর প্রথম আইটেম এর সাথে compare করবো যদি আইটেম গুলো লিস্ট এর প্রথম আইটেম এর থেকে বড় হয় তাহলে আইটেম থেকে প্রথম আইটেম বিয়োগ করে বিয়োগফলক count_sum এর সাথে যোগ করবো

while True:
    l = []
    n = int(input())
    if n == 0:
        break
    else:

        for i in range(n):
            s = input()
            # l = len(n)
            c = s.count(" ")
            l.append(c)

        l.sort()
        ll = len(l)

        count_sum = 0
        for j in range(ll):
            if l[j] > l[0]:
                d = l[j] - l[0]
                count_sum += d

        print(count_sum)

 

Uncategorized

পাইথন ব্যাবহার করে চতুর্ভূজ দিয়ে বৃত্ত আঁকি

by , on
April 4, 2018

পাইথনের turtle মডিউল ব্যাবহার করে চমৎকার গ্রাফিক্সের কাজ করা যায়। নিচের কোড টুকু প্রথমে কপি পেষ্ট করে টার্মিনালে রান করুন। এরপর পড়ে বোঝার চেষ্টা করুন

import turtle

def draw_square():
    window = turtle.Screen()
    window.bgcolor("red")
    
    brad = turtle.Turtle()
    brad.shape("turtle")
    brad.color("yellow")
    brad.speed(5)
    counter = 0
    while counter < 36:
        brad.forward(100)
        brad.right(90)
        brad.forward(100)
        brad.right(90)
        brad.forward(100)
        brad.right(90)
        brad.forward(100)
        brad.right(100)
        counter += 1

    window.exitonclick()

if __name__ == "__main__":
    draw_square()

Uncategorized

CSRF Token কি এবং কেন ব্যবহার করা হয়!?

by
, on
March 28, 2018

CSRF বা Cross-Site Request Forgery হল এক ওয়েবসাইট থেকে আরেক ওয়েবসাইটে আপনার ব্রাউজারের মাধমে রিকুয়েস্ট সেন্ড করা! কঠিন হয়ে গেল? আচ্ছা সহজ করি…

১) ধরুন কোন ওয়েব ব্রাউজার দিয়ে আপনি ফেসবুকে লগিন করেছেন। সেখানে স্ট্যাটাস পোস্ট করার জন্য একটা ফর্ম আছে। আপনি সেখানে কিছু লিখে সাবমিট করলেই সেটা পাবলিশ হয়ে যায়!

২) আচ্ছা, আপনি কি প্রতিবারই পোস্ট করার সময় ইউজার নেম এবং পাসওয়ার্ড দিয়ে পোস্ট করেন? না। তাহলে ফেসবুক কিভাবে বুঝে যে এই ফর্মটা আপনিই সাবমিট করেছেন? সিম্পল ব্যপার, সেই ব্রাউজার দিয়ে তো আপনি ফেসবুকে লগিন করেছিলেন, তাই ফেসবুক এটা ধরে নিয়েছে যে আপনার এই ব্রাউজার থেকে আসা রিকুয়েস্ট গুলো আপনিই করছেন!

৩) আপনি কি জানেন যে জাভাস্ক্রিপ্ট নামে একটি প্রোগ্রামিং ল্যাঙ্গুয়েজ রয়েছে যা প্রায় সকল ওয়েবসাইটেই থাকে এবং সেটা দিয়ে যেকোন ধরনের ফর্ম নিমেষেই তৈরি করে ফেলা যায় এবং যেখানে সেখানে তা সাবমিট করা যায়? ধরে নিলাম যে আপনি জানেন না!!

৪) কোন এক কারনে আপনি এমন একটি ওয়েবসাইটে গেলেন যেটাতে এমন একটি জাভাস্ক্রিপ্ট কোড রয়েছে যা হুবুহু ফেসবুক স্ট্যাটাস ফর্মের মত একটা ফর্ম তৈরি করে সেটাতে যেকোন কিছু লিখে সরাসরি ফেসবুকের ওয়েবসাইটেই সাবমিট করে দিল!!! অথচ আপনি জানতেই পারলেন না! (এটা সম্ভব কিন্তু! )

৫) ফেসবুক যখন সেই জাভাস্ক্রিপ্ট থেকে অটো জেনারেট হওয়া রিকুয়েস্ট টা পাবে সে কিন্তু ধরে নিবে যে রিকুয়েস্টটা আপনি করেছেন! ( কেন? কারন সেটা আপনার ব্রাউজার থেকে গিয়েছে এবং এই ব্রাউজার দিয়েই আপনি ফেসবুকে লগিন করে বসে আছেন!)

৬) অন্য একটা ওয়েবসাইট থেকে একটা জাভাস্ক্রিপ্ট কোড উলটা পালটা কিছু লিখে আপনার ফেসবুকে পাবলিশ করে দিল, এই বিষয়টা যদি আপনার মাথা ব্যথার কোন কারন না হয় তাহলে আপনি আসলেই খুব শান্তিতে আছেন! ( তবে সেই ভয়ংকর কোডটা যে শুধু আপনার ফেসবুকেই রিকুয়েস্ট সাবমিট করতে পারবে এমন নয়, ইকমার্স, ব্যাংক বা ফিন্যানশিয়াল অথবা পারসোনাল যেকোন ওয়েবসাইটেই কিন্তু সে এরকম রিকুয়েস্ট পাঠাতে পারবে!!)

৭) CSRF এটাকেই বলে। এক ওয়েবসাইট থেকে আরেক ওয়েবসাইটে আপনার ব্রাউজারের মাধ্যমে রিকুয়েস্ট করা। (এবং অবশ্যই আপনার অজান্তে)

৮) CSRF টোকেন হল এই ধরনের ক্রস সাইট রিকুয়েস্ট থেকে বাচার সিস্টেম! এটা জাস্ট একটা র‍্যান্ডম কিছু অক্ষরের স্ট্রিং। যা অটো জেনারেট হয় এবং ভেরিফাই হয়। আবারো কঠিন লাগছে!?

৯) ধরুন ফেসবুক বুদ্ধি করে তার প্রতিটা ফর্মের সাথে গোপনে একটা র‍্যান্ডম স্ট্রিং আপনার ব্রাউজারে পাঠিয়ে দিল, যখন আপনি ফর্ম সাবমিট করবেন তখন সেই স্ট্রিং টাও আবার ফেসবুকের সার্ভারে যাবে। ফেসবুক তখন ভেরিফাই করে দেখবে যে সে যে স্ট্রিং টা ব্রাউজারে পাঠিয়েছিল সেটাই কি সাবমিটের সময় আবার সার্ভারে ফিরে গেছে কিনা! যদি ফিরে যায় তাহলে রিকুয়েস্ট এক্সেপ্ট করবে অন্যথায় করবেনা!

১০) অন্য কোন ওয়েবসাইটের জাভাস্ক্রিপ্ট কোড ফেসবুকের মত ফর্ম তৈরি করতে পারলেও সেই CSRF Token এর র‍্যান্ডম স্ট্রিং টা তৈরি করতে পারবেনা। কারনে এটা র‍্যান্ডম, প্রতিটা ফর্মের জন্য আলাদা, প্রতিবার লোড হওয়ার সময় চেঞ্জ হয় এবং সেখানে এনকোডিং এর মাধ্যমে গোপনে ভ্যালিডিটির টাইমও সেট করা থাকে যে পাঁচ মিনিট বা দশ মিনিট পর আর এই কোড দিয়ে ফর্ম সাবমিট করলেও এক্সেপ্ট করবেনা!
এমনকি জাভাস্ক্রিপ্ট এর মাধ্যমে অন্য কোন ওয়েবসাইট ফেসবুকের এই CSRF Token (যেটা ফেসবুক আপনার ব্রাউজারে পাঠিয়েছে) কপি করেও নিতে পারবেনা! কারন আপনার ব্রাউজারটিই একাজ তাকে করতে দিবেনা!

১১) সো, যেহেতু আপনি সরাসরি ফর্ম সাবমিট করলে ভ্যালিড CSRF Token সহ সাবমিট হচ্ছে পক্ষান্তরে অন্য কোন ওয়েবসাইটের জাভাস্ক্রিপ্টের করা ফর্ম সেই CSRF Token দিতে পারছেনা তাই আপনার রিকুয়েস্ট গ্রহণ করা হবে এবং অন্যদেরটা গ্রহণ করা হবেনা!! সিম্পল!

জ্যাঙ্গোতে একারনেই (POST রিকুয়েস্টে) ফর্মের ক্ষেত্রে csrf token যুক্ত করা আবশ্যক! বোঝা গেল জিনিষটা?

 

আরো জানতে চাইলেঃ  https://en.wikipedia.org/wiki/Cross-site_request_forgery

Uncategorized

১ম ধাপ – প্রডাক্ট লিষ্ট তৈরী

by , on
March 28, 2018

আসসালামুয়ালাইকুম,
আপনার জ্যাঙ্গো শেখা কেমন চলছে ? আশা করি আপনি জ্যাঙ্গো নিয়ে ছোটখাট অনেক কাজ করতে শিখেছেন। এখন আমরা একটি প্রজেক্ট করার মাধ্যমে আমাদের পূর্বের শেখাকে আরো মজবুত করব। কিভাবে একটি প্রজেক্ট শুরু করতে হয় তা আমি আগের পোষ্টে আলোচনা করেছি। আশা করি আপনার কাছে বিষয়টি বোধগম্য হয়েছে।

আমরা বর্তমান প্রজেক্টটি Django 2 এবং Python 3 ভার্সনে কোড করব। সম্পুর্ন প্রজেক্টের প্রতিটি ধাপে KanBan Board অনুসরন করার চেষ্টা করব ইনশাআল্লাহ।

গত পর্বে KanBan Board এ TODO লিষ্ট তৈরী করেছিলাম

 

সর্বপ্রথম আমাদের দোকানে যে পন্যগুলো থাকবে তার লিষ্ট তৈরী করা দরকার। এজন্য  Items কে In Progress এ নিয়ে গিয়ে আমাদের কাজ শুরু করব

আমাদের চেকলিষ্টের প্রথম কাজ start project and app শুরু করি।

প্রজেক্ট শুরু

প্রজেক্টের মডিউলের ভার্সন ম্যানেজ করার জন্য virtual environment তৈরী করি।

virtualenv dokan-env --python=python3

“dokan-env” হচ্ছে virtual environment এর নাম এবং  –python=python3 দ্বারা বলে দেয়া হয়েছে যে আমরা python3 ব্যাবহার করব। আপনার পিসিতে অবশ্যই python3 ইন্সটল করা থাকতে হবে।

Activate virtualenv

source dokan-env/bin/activate

install Django

pip install django==2

প্রজেক্ট শুরু করি

django-admin startproject dokan

app তৈরী করি

python manage.py startapp inventory

settings.py এ installed_apps এ ‘inventory’ যুক্ত করি।

আমাদের দোকানে কি কি পন্য থাকবে তার ডাটা ডাটাবেজে রাখার জন্য মডেল ক্লাস তৈরী করি।
inventory/models.py

from django.db import models

class Category(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name 


class Item(models.Model):
    name = models.CharField(max_length=150)
    category = models.ForeignKey(Category, on_delete=None)
    is_active = models.BooleanField(default=True)
    
    def __str__(self):
        return self.name

এডমিন প্যানেলে রেজিষ্টার করি
inventory/admin.py

from django.contrib import admin
from .models import Category, Item

admin.site.register(Category)
admin.site.register(Item)

মাইগ্রেট করি

python manage.py makemigrations
python manage.py migrate

superUser তৈরী করে এডমিন প্যানেলে লগিন করি এবং Category ও Item তৈরী করি।

Item List পেজ তৈরী

সবগুলো আইটেমের তালিকা দেখার জন্য একটি ভিউ তৈরী করি।
inventory/views.py

from django.shortcuts import render
from .models import Item

def item_list(request):
    all_items = Item.objects.all()
    context = {'all_items':all_items}
    return render(request, 'inventory/item_list.html', context)

settings.py এ TEMPLATES  এর ‘DIRS’: [‘templates’] যুক্ত করি।  ( বিস্তারিত )
প্রজেক্ট ডিরেক্টরীতে templates নামে একটি ডিরেক্টরী তৈরী করি এবং এর মধ্য আরেকটি inventory নামে ডিরেক্টরী তৈরী করি।

templates/inventory/item_list.html

  {% for item in all_items %}
        <p>{{item }}</p>
    {% endfor %}

inventory/urls.py

from django.urls import path
from .views import item_list


urlpatterns = [
    path('items/', item_list, name='item-list'),
]

এখন localhost:8000/inventory/items এ গিয়ে সকল আইটেমগুলো দেখতে পাবেন।

Style যুক্ত করি

[ style যোগ করার বিস্তারিত টিউটোরিয়াল দেখুন এখানে ]

Bootstrap SB Admin 2  থিম ব্যাবহার করে আমরা আমাদের প্রজেক্ট ডিজাইন করব।

রুট ডিরেক্টরীতে ( যেখানে manage.py রয়েছে) static নামে একটি ডিরেক্টরী তৈরী করি। settings.py ফাইলে বলে দিই যে, আমাদের সকল static ফাইল ( html, css, js ) এই ডিরেক্টরীতে থাকবে।
settings.py

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

templates/base.html

<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>My dokan</title>
    {% load staticfiles %}
    <!-- Bootstrap Core CSS -->
    <link href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">

    <!-- MetisMenu CSS -->
    <link href="{% static 'vendor/metisMenu/metisMenu.min.css' %}" rel="stylesheet">

    <!-- Custom CSS -->
    <link href="{% static 'dist/css/sb-admin-2.css' %}" rel="stylesheet">

    <!-- Morris Charts CSS -->
    <link href="{% static 'vendor/morrisjs/morris.css' %}" rel="stylesheet">

    <!-- Custom Fonts -->
    <link href="{% static 'vendor/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css">

</head>

<body>

    <div id="wrapper">

        <!-- Navigation -->
        <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="http://www.banglai-django.com/">বাংলায় জ্যাঙ্গো</a>
            </div>
            <!-- /.navbar-header -->

            <ul class="nav navbar-top-links navbar-right">
                
                <!-- /.dropdown -->
                <li class="dropdown">
                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
                        <i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i>
                    </a>
                    <ul class="dropdown-menu dropdown-user">
                        <li><a href="#"><i class="fa fa-user fa-fw"></i> User Profile</a>
                        </li>
                        <li><a href="#"><i class="fa fa-gear fa-fw"></i> Settings</a>
                        </li>
                        <li class="divider"></li>
                        <li><a href="login.html"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
                        </li>
                    </ul>
                    <!-- /.dropdown-user -->
                </li>
                <!-- /.dropdown -->
            </ul>
            <!-- /.navbar-top-links -->

            <div class="navbar-default sidebar" role="navigation">
                <div class="sidebar-nav navbar-collapse">
                    <ul class="nav" id="side-menu">
                        
                        <li>
                            <a href="{% url 'item-list' %}"><i class="fa fa-dashboard fa-fw"></i> Item List</a>
                        </li>
                        
                        <li>
                            <a href="#"><i class="fa fa-table fa-fw"></i> Tables</a>
                        </li>
                        <li>
                            <a href="#"><i class="fa fa-edit fa-fw"></i> Forms</a>
                        </li>
                        
                    </ul>
                </div>
                <!-- /.sidebar-collapse -->
            </div>
            <!-- /.navbar-static-side -->
        </nav>

        <div id="page-wrapper">
            <!-- Title Block -->
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">{% block pagetitle %}{% endblock %}</h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- Container Block -->
            <div class="row">
            
                {% block container %}
                {% endblock %}
            </div>
            <!-- /.row -->

        </div>
        <!-- /#page-wrapper -->
    </div>
    <!-- /#wrapper -->

    <!-- jQuery -->
    <script src="{% static 'vendor/jquery/jquery.min.js' %}"></script>

    <!-- Bootstrap Core JavaScript -->
    <script src="{% static 'vendor/bootstrap/js/bootstrap.min.js' %}"></script>

    <!-- Metis Menu Plugin JavaScript -->
    <script src="{% static 'vendor/metisMenu/metisMenu.min.js' %}"></script>

    <!-- Morris Charts JavaScript -->
    <script src="{% static 'vendor/raphael/raphael.min.js' %}"></script>
    <script src="{% static 'vendor/morrisjs/morris.min.js' %}"></script>
    <script src="{% static 'data/morris-data.js' %}"></script>

    <!-- Custom Theme JavaScript -->
    <script src="{% static 'dist/js/sb-admin-2.js' %}"></script>

</body>

</html>

এখন item_list.html কে পরিবর্তন করে সুন্দর কাঠামো দান করি
templates/inventory/item_list.html

{% extends 'base.html' %}

{% block pagetitle %} All Items {% endblock %}

{% block container %}

<div class="col-md-12">
    <div class="panel panel-default">
        <div class="panel-body">
            <div class="table-responsive">
                <table class="table table-striped table-bordered table-hover">
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>Name</th>
                            <th>Category</th>
                            <th>Is Active</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for item in all_items %}
                            <tr>
                                <td>{{ forloop.counter }}</td>
                                <td>{{ item.name }}</td>
                                <td>{{ item.category }}</td>
                                <td>{{ item.is_active }}</td>
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>
    
{% endblock %}

localhost:8000/inventory/items/ এ গেলে নিচের চেহারা দেখতে পাবেন

আমরা আমাদের ১ম টার্গেট পূরন করতে পেরেছি। trello.com এ গিয়ে বোর্ড আপডেট করুন

GitHub এ কোড পুশ করা

[ git এবং GitHub সম্পর্কে জানতে জাকির হোসেন ভায়ের লেখাটি দেখুন ]

আমাদের এই প্রজেক্টটি গিটহাবে পুশ করব। github.com এ গিয়ে নতুন রিপজিটরী খুলুন

এখন কি করতে হবে, গিটহাব আমাদেরকে তা লিখেই দিয়েছে খুব সহজে

git init 
git add . 
git commit -m "Item list completed"
git remote add origin https://github.com/harunurkst/dokan.git
git push origin master

git remote add origin https://github.com/harunurkst/dokan.git এই লাইনটিতে আপনার রিপজিটরী url বাসান

কেমন লাগলো প্রজেক্টটি করতে? আশা করি ভাল লেগেছে। কমেন্টে আপনার অনুভুতি জানান। আগামি পর্বে প্রজেক্টের ২য় পর্ব দেখাবো ইনশাআল্লাহ।