با عرض سلام و وقت بخیر خدمت کاربران محترم سایت ویرگول، در این مقاله آموزشی که چکیده آموزش جنگو ORM از سایت Django documentation بهمراه مطالب تکمیلی تر , سعی شده یک آموزش کاربردی و پروژه محور از جنگو ORM ارایه گردد.ایده این سری مقاله های آموزشی از این موضوع سرچشمه می گیرد که بخشی از خوانندگان وجود دارد که به محتوای نوشتاری آنلاین بهتر پاسخ می دهند و ترجیج می دهند مهارت های جدید را به سرعت از طریق خواندن افزایش دهند.این سری آموزش ها با ارایه اولین پکیج آموزشی در خصوص جنگو آغاز می شود که انتظار می رود با واکنش مثبت کاربران همراه شود.
توجه: این مقاله به مرور زمان، ویرایش و یا تکمیل میشود!
تقاضا: در صورتی که با مشکل تایپی، دستوری و یا مفهومی در این مقاله برخورد کردید، از شما دوست عزیز و گرامی، صمیمانه تقاضا میکنم که اینجانب را مطلع کرده، تا نسبت به تصحیح و یا تکمیل آن، در اسرع وقت، اقدام نمایم. با کمال تشکر جواد جهانگیری
شماره تلفن همراه: 09149431772
نشانی پست الکترونیکی: javad.jahangiri.niopdc@gmail.com
فیلمهای آموزشی در آپارات:جواد جهانگیری (CTO) - آپارات
فیلم آموزشی در یوتویب: javad jahangiri - YouTube
نسخه مقاله: ۱.۱ - تاریخ بروزرسانی: 1401/01/07
برای دیدن فیلم اموزشی مربوطه به کانال آپاراتی بنده به ادرس جواد جهانگیری (CTO) - آپارات مراجعه نمایید
برای این اموزش از منابع زیر استفاده شده است
Django | Documentation |Making queries |Complex lookups with Q objects
Django | Documentation | Search
نکته:سورس های این پروژه در گیت هاب بنده در مسیر ذیل قابل دسترس می باشد:https://github.com/javadjahangiriniopdc/djangosearch
حتما قبل از شروع به مطالعه این مقاله حتما مقاله قبلی بنده در راستا اموزش Django Orm از طریق لینک ذیل مطالعه فرمایید
ابتدا یک پروژه جنگو ایجاد می کنیم پیشنهاد می شود برای کار با جنگو از IDE PyCharm استفاده نمایید و به شرح ذیل یک پروژه جنگو ایجاد می کنیم
وارد پنجره run manager.py task به شرح ذیل می شویم
یک app جدید بنام myapp ایجاد می کنیم
و app جدید به app های جنگو به شرح ذیل اضافه می کنیم
در app جدید اضافه شده در فایل models.py یک موجودیت بنام Person به شرح زیر ایجاد می کنیم
درنهایت یک مایگریشن ایجاد کرده و تغییرات بر روی دیتابیس مایگریت می کنیم
یک سوپر کاربر ایجاد می نماییم:
و موجودیت را به پنل admin اضافه می کنیم
وارد پنل admin جنگو شده و چندین رکورد برای جدول Person درج می کنیم:
به اپ جدید myapp یک فایل urls.py به صورت زیر اضافه می کنیم :
و در نهایت urls.py جدید اضافه شده در app اصلی جنگو به شکل زیر include می کنیم
در نهایت داخل فایل views.py شده و یک function view به شرح ذیل بنام home ایجاد می کنیم
و یک فایل home.html به مسیر template اضافه می کنیم:
دقت شود در جنگو برخی از اسامی دارای معنی خاصی هستند مانند static و templates اگر دقت شود در داخل فایل settings.py در قسمت تنظیمات static و templates تنظیماتی به شرح ذیل اعمال شده این به این معنی می باشد که جنگو در داخل هر app به دنبال پوشه های مذکور می گردد و برای سرویس از این پوشه ها استفاده می کند
در مورد پوشه templates اولویت ابتدا با templates که در مسیر root جنگو می باشد هست و سپس templates موجود در داخل هر app این به این معنی می باشد که اگر شما در داخل پوشه templates که در مسیر root جنگو یک فایل برای مثال index.html داشته باشید و در داخل پوشه templates که در مسیر هر app هم با این نام فایلی موجود باشد اولویت با index.html می باشد که در پوشه templates که در مسیر root جنگو هست
برای تنظیم فایل های static تنظیمات مقتضی توسط خود جنگو بصورت پیش فرض اعمال شده است و نیازی به اعمال تنظیم خاصی نیست ولی دقت شود در پایان برنامه نویسی پروژه در هنگام collectstatic نیاز به مسیر مربوط STATIC_ROOT دارد که به شکل زیر تنظیم می شود:
STATIC_URL = 'static/' import os STATIC_ROOT = os.path.join(BASE_DIR, 'static')
پیشنهاد می شود در داخل هر app دو پوشه بنام های static و templates ایجاد شود و در داخل هر پوشه یاد شده یک پوشه هم نام خود app ایجاد گردد دلیل این پیشنهاد این است که در نهایت که پوشه برای مد product اماده می شود در هنگام collectstatic تمامی فایل موجود در پوشه های static و templates هر app در یک پوشه static و templates در مسیر root جنگو تجمیع می گردد در این صورت اگر فایل هم نامی در app های ما باشد به مشکل جدی برخورد می کنیم ولی وقتی در داخل هر app در پوشه های static و templates یک پوشه بنام خود app ایجاد شود در هنگام تجمیع شدن در نهایت در یک پوشه واحد فایل هر app در داخل پوشه هم نام با خود app کپی می شود این مشکل تداخل نام دیگر وجود نخواهد داشت.
همانطوری که در تصویر بالا مشاهده می کنید در داخل پوشه myapp یک پوشه بنام static ایجاد شده است و در داخل پوشه static هم یک پوشه بنام myapp همان با نام خود app ایجاد شده و همین کار برای پوشه templates هم تکرار شده است این کار مشکل تجمیع فایل در نهایت در پوشه های static و templates (فلش سوم) که در مسیر root پروژه جنگو در نهایت پس از پایان پروژه را مرتفع خواهد نمود.
برای قالب پروژه پیشنهاد می شود از یکی از قالب های اموزشی موجود در سایت w3schools به شرح ذیل استفاده شود
بر روی گزینه try your self کلیک نمایید و کد زیر برای شما نمایش داده می شود:
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap 4 Website Example</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css"> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.slim.min.js"> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"> <style> .fakeimg { height: 200px; background: #aaa; } </style> </head> <body> <div class="jumbotron text-center" style="margin-bottom:0"> <h1>My First Bootstrap 4 Page</h1> <p>Resize this responsive page to see the effect!</p> </div> <nav class="navbar navbar-expand-sm bg-dark navbar-dark"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="collapsibleNavbar"> <ul class="navbar-nav"> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> </ul> </div> </nav> <div class="container" style="margin-top:30px"> <div class="row"> <div class="col-sm-4"> <h2>About Me</h2> <h5>Photo of me:</h5> <div class="fakeimg">Fake Image</div> <p>Some text about me in culpa qui officia deserunt mollit anim..</p> <h3>Some Links</h3> <p>Lorem ipsum dolor sit ame.</p> <ul class="nav nav-pills flex-column"> <li class="nav-item"> <a class="nav-link active" href="#">Active</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#">Disabled</a> </li> </ul> <hr class="d-sm-none"> </div> <div class="col-sm-8"> <h2>TITLE HEADING</h2> <h5>Title description, Dec 7, 2017</h5> <div class="fakeimg">Fake Image</div> <p>Some text..</p> <p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p> <br> <h2>TITLE HEADING</h2> <h5>Title description, Sep 2, 2017</h5> <div class="fakeimg">Fake Image</div> <p>Some text..</p> <p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p> </div> </div> </div> <div class="jumbotron text-center" style="margin-bottom:0"> <p>Footer</p> </div> </body> </html>
در داخل پوشه myapp/templates/myapp یک فایل بنام base.html ایجاد می کنیم و از طریق کدهای بالا به شرح ذیل این فایل را تغییر می دهیم
base.html
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap 4 Website Example</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="{% static 'myapp/css/bootstrap.min.css' %}"> <script src="{% static 'myapp/js/jquery.slim.min.js' %}"> <script src="{% static 'myapp/js/popper.min.js' %}"> <script src=" {% static 'myapp/js/bootstrap.bundle.min.js' %}"> <style> .fakeimg { height: 200px; background: #aaa; } </style> </head> <body> {% include 'myapp/header.html' %} <div class="container" style="margin-top:30px"> {% block content %} {% endblock %} </div> {% include 'myapp/footer.html' %} </body> </html>
ابتدا فایل css و js مورد نیاز به شرح ذیل در پوشه myapp/static/myapp در داخل پوشه های cssوjs کپی می کنیم
{% load static %}
<script src="{% static 'myapp/js/jquery.slim.min.js' %}"> <script src="{% static 'myapp/js/popper.min.js' %}"> <script src=" {% static 'myapp/js/bootstrap.bundle.min.js' %}">
header.html
<div class="jumbotron text-center" style="margin-bottom:0"> <h1>My First Bootstrap 4 Page</h1> <p>Resize this responsive page to see the effect!</p> </div> {% include 'myapp/nav.html' %}
کد مورد نیاز برای include کردن header.html در داخل فایل base.html
{% include 'myapp/header.html' %}
معمولا در پروژه های قسمت navigation ها (منوها) نیز به یک فایل جداگانه منتقل شده و در داخل header.html به شکل بالا include می شود
nav.html
<nav class="navbar navbar-expand-sm bg-dark navbar-dark"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="collapsibleNavbar"> <ul class="navbar-nav"> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> </ul> </div> </nav>
<div class="container" style="margin-top:30px"> {% block content %} {% endblock %} </div>
index.html
{% extends 'myapp/base.html' %} {% load static %} {% block content %} <div class="row"> <div class="col-12"> <h1>index content</h1> </div> </div> {% endblock %}
کد {% extends 'myapp/base.html' %} زیر برای ارث بری از صفحه base.html استفاده می شود در این صورت در هنگام بارگذاری صفحه index.html ابتدا صفحه base.html بارگذاری شده و سپس در داخل قسمت block content کدهای مربوط به صفحه index.html بارگذاری می شود
footer.html
<div class="jumbotron text-center" style="margin-bottom:0"> <p>Footer</p> </div>
اگر تنظیمات به درستی انجام شود در نهایت شما با خروجی به شکل ذیل روبه رو خواهید شد
from django.shortcuts import render from myapp.models import Person def home(request): persons = Person.objects.all() return render(request, 'myapp/index.html', {'persons': persons})
سپس کدهای مورد نیاز برای ایجاد جدول بوت استرپی را از لینک زیر استفاده کنید
https://getbootstrap.com/docs/4.0/content/tables/
وکدهای جدول بوت استرپی به شرح ذیل به صفحه Index اضافه می کنیم
index.html
{% extends 'myapp/base.html' %} {% load static %} {% block content %} <div class="row"> <div class="col-12"> <table class="table"> <thead> <tr> <th scope="col">name</th> <th scope="col">description</th> </tr> </thead> <tbody> {% for person in persons %} <tr> <td>{{ person.name }}</td> <td>{{ person.description }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> {% endblock %}
و خروجی به شرح ذیل خواهد بود
یک فرم جنگو به پروژه به شرح ذیل اضافه می کنیم
forms.py
from django import forms class SearchForm(forms.Form): search = forms.CharField()
حالا تغییرات ذیل در فرم view.py به شرح ذیل اضافه می کنیم :
https://docs.djangoproject.com/en/4.0/topics/db/queries/#complex-lookups-with-q-objects
همچنین برای جستجو کردن به شرطی که شامل یک عبارت باشد و به حروف کوچیک و بزرگ هم حساس نباشد از icontains استفاده شده است
views.py
from datetime import datetime from django.db.models import Q from django.http import HttpResponse from django.shortcuts import render from myapp.forms import SearchForm from myapp.models import Person def home(request): persons = Person.objects.all() form = SearchForm() if 'search' in request.GET: form = SearchForm(request.GET) if form.is_valid(): cd = form.cleaned_data['search'] persons= persons.filter(Q(name__icontains=cd) | Q(description__icontains=cd)) return render(request, 'myapp/index.html', {'persons': persons, 'form': form})
حالا در فایل index.html یک ردیف جدید بوت استرپی ایجاد کرده و به شرح ذیل فرم که در مرحله قبل به این صفحه پاس شده است را به صفحه html اضافه می کنیم:
index.html
{% extends 'myapp/base.html' %} {% load static %} {% block content %} <div class="row"> <div class="col-12"> <form action=""> {{ form }} <input type="submit" value="Search"> </form> </div> </div> <div class="row" style="margin-top: 50px"> <div class="col-12"> <table class="table"> <thead> <tr> <th scope="col">name</th> <th scope="col">description</th> </tr> </thead> <tbody> {% for person in persons %} <tr> <td>{{ person.name }}</td> <td>{{ person.description }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> {% endblock %}
و در نهایت نتیجه خروجی برنامه به شرح ذیل خواهد بود
در دوره های آموزش تضمینی مجتمع فنی ارومیه که به صورت خصوصی و عمومی در دو شیوه حضوری و آنلاین برگزار می شود سرفصل های بسیار متنوع و کاربردی را بصورت پروژه محور آموزش داده می شود تا شخص کارآموز بتواند بلافاصله پس از اتمام این دوره در کمترین زمان ممکن وارد بازار کار شود.
آموزش تخصص ماست با ما حرفه ای شوید
جهت مشاوره با شماره 09149431772 در ارتباط باشید ...