انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید




نویسنده موضوع: با هم جنگو یاد بگیریم  (دفعات بازدید: 6532 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
با هم جنگو یاد بگیریم
« : 04 مهر 1398، 08:37 ب‌ظ »
سلام دوستان
حوصله ام سر رفته بود تصمیم گرفتم که یه اموزش برای جنگو بنویسم یه ذره اشو الان مینویسم بقیه اش رو هم توی پست های دیگه مینویسم میزارم براتون
خب اول ببینیم جنگو چیه؟ جنگو یه فریمورک وبه توی پایتون که خیلی از سایت های بزرگ با اون نوشته شده اند مثلا اینستاگرام پینترست و ... (یه فهرست بلند بود اینا الان خاطرم هستش) جنگو از فریمورک های mvc هستش یعنی model view controller خیلی چیز پیچیده ای نیستش شما فقط کافیه یه مقدار دقت کنید
خب اول ببینیم چطوری یه پروژه رو شروع کنیم
اول نصب میکنیم پیشنهاد میدهم از یه container استفاده کنید اولش برای سهولت کار برای مثال virtualenv توی این اموزش استفاده میشه برای ایجاد یه محیط ویرچوال انو بنویسید:
virtualenv -p /usr/bin/activate .venvسوییچ پی رو نوشتم تا اگر رو سیستمتون پایتون دو هست قاطی نشه اسمش هم با نقطه شروع شده تا فایلها نمایش داده نشوند
سپس با پیپ جنگو را روی ویرچوال انو نصب میکنیم ولی قبش باید ویرچوال انو فعال باشه
source .venv/bin/activatepip install djangoبعد از اینکه جنگو نصب شد با دستور زیر پروژه را شروع میکنیم:
django-admin startproject MyTestProjectاز این طریق پروژه اغاز میشه ولی به یه اپ هم نیاز داره چون جنگو ماژولاره و هر ماژول یه کاری انجام میده برای ساختن اپ مینویسم :
python manage.py startapp MyAppفایل manage.py خط فرمان جنگو را تشکیل می دهد
حالا ما دو پوشه داریم یکی شامل فایل پروژه و یکی مال اپ
در مال اپ سه فایل مهم هستش:
admin.py مربوط به ریجستریشن های پنل ادمین جنگو هستش که بعدا میفهمید
models.py مال مدل ها و دیتا بیس هستش
views.py هم مال ویو های و هندل درخواست های وب هستش
بعدا درباره ی اینا توضیح میدیم
توی پوشه اصلی پروژه دوفایل مهم هستش:
settings.py که مسیر اصلی پروژه زبان ساعت و سکرت مربوز به رمزنگاری درون ان هستش(نکته:در لیست اپ های نصب شده اپ هایی که ساختید رو بنویسید)
urls.py که مربوط به ادرس هایی است که به هر ویو هندل میشه
خب تا الان یکم توضیح دادیم امیدوارم فرصت بشه ادامه بدم  :D ;D

آفلاین esmaeelE

  • ناظر انجمن
  • *
  • ارسال: 1253
  • جنسیت : پسر
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #1 : 04 مهر 1398، 09:43 ب‌ظ »
خیلی خوبه
امیدوارم ادامه دار باشه
چند مطلب به نظرم رسید.
 
  • درباره virtualenv  و مزایای استفاده ازش بیشتر توضیح بدین
  • کاربرد‌های جانگو و سایتایی که الان باهاش در حال سرویس دهی هستند رو بیان کنید
  • و یک سوال وقتی با پایتون 3 کار می‌کنیم دستور پیپ نباید pip3  باشه؟
برای اینکه آموزشتون مستقلاً قابل استفاده و کامل باشه
اینا رو اضافه کنید.

نصب virtual enviornonment
sudo apt install virtualenv
ساخت virtual env هم به نظرم با این دستور صحیح باشه

virtualenv -p /usr/bin/python3 .venv
چطور آخرین نسخه از جنگو را نصب کنیم (  LTS 3.2 ) با پیپ 2.2.5 نصب شد.

قبل از دستور زیر لازمه یک cd MyTestProject بزنیم.
python manage.py startapp MyApp
خیلی خوب میشه که تو همین پستای اول پروژه hello world رو راه بندازین.

لینک مرتبط

نسخه‌ای از پایتون، جانگو و سایر ابزارهایی که باهاش آموزشو پیش می‌برید دقیقا اعلام کنید.
« آخرین ویرایش: 04 مهر 1398، 09:58 ب‌ظ توسط esmaeelE »

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #2 : 04 مهر 1398، 11:28 ب‌ظ »
خیلی خوبه
امیدوارم ادامه دار باشه
چند مطلب به نظرم رسید.
 
  • درباره virtualenv  و مزایای استفاده ازش بیشتر توضیح بدین
  • کاربرد‌های جانگو و سایتایی که الان باهاش در حال سرویس دهی هستند رو بیان کنید
  • و یک سوال وقتی با پایتون 3 کار می‌کنیم دستور پیپ نباید pip3  باشه؟
برای اینکه آموزشتون مستقلاً قابل استفاده و کامل باشه
اینا رو اضافه کنید.
نصب virtual enviornonment
sudo apt install virtualenv
ساخت virtual env هم به نظرم با این دستور صحیح باشه

virtualenv -p /usr/bin/python3 .venv
چطور آخرین نسخه از جنگو را نصب کنیم (  LTS 3.2 ) با پیپ 2.2.5 نصب شد.

قبل از دستور زیر لازمه یک cd MyTestProject بزنیم.
python manage.py startapp MyApp
خیلی خوب میشه که تو همین پستای اول پروژه hello world رو راه بندازین.

لینک مرتبط

نسخه‌ای از پایتون، جانگو و سایر ابزارهایی که باهاش آموزشو پیش می‌برید دقیقا اعلام کنید.
ممنون از نظرتون درباره ویرچوال انو نخواستم طولانی کنم خیلی به خاطر این زیاد توضیح ندادم به علاوه جدیدترین نسخه جنگو همون 2.2.5 هستش
وقتی ویرچوال انو فعال باشه پیپ همون پیپ ۳ هستش لازم نیست حتما مشخص باشه
پروژه هم میخوام یه API شبیه استک اور فلو بنویسم البته یه API هستش نه سایت اچ تی ام ال

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #3 : 04 مهر 1398، 11:51 ب‌ظ »
کاربرد جنگو در طراحی سرور و API های RESTful هستش
من میخوام یه پروژه بنویسم که یه API باشه برای چیزی شبیه استک اور فلو که مردم توش سوال بپرسن و بقیه جواب بدن یعنی یه API فروم وار شبیه همین جا
خب الان میرم سراغ مدل ها
طبیعتا باید یه دیتا بیسی باشه تا سوالات مردم رو ذخیره کنیم
مدل ی شی هستش پس باید به شکل کلاس تعریف بشه به فایل models.py میریم آنجا یسری ایمپورت هست که یکیش (که معمولا همون یکی فقط)این هستش که :
from django.db import modelsکه متود مدل هارو فراخانی میکنه خب یه کلاس تعریف میکنیم مال سوال بعد یسری فیلد توش مینویسیم که فیلد های دیتا بیس هستن و این فیلد ها انواعی دارن مثلا چندتا از انها:
charField,integerField,BooleanField ,EmailField و .. هستن
خب یه مدل معیار این شکلیه:

class question(models.Model):

       text=models.CharField(max_length=255)
الان یه کلاس درست کردیم که توش یه فیلد تکست هستش که از نوع کاراکتر فیلد هستش و اکثر طولش ۲۵۵ هسنش
به جز فیلد های عادی که کاربردشون مشخصه یکسری رابطه هست که یک فیلد رو به یک شی یا یک فیلد دیگر مشخص میکنند مثلا ما سوال را به یوزر متصل میکنیم (که یک مدل است نه فیلد چون فیلد های یوزر نیم پسورد ایمیل و .. دارد)
user=models.ForeignKey(User,on_delete=models.CASCADE)
پارامتر دوم یعنی ان دیلیت یعنی اگر شی User حذف شد فیلد user هم حذف شود
نکته:برای ایمپورت کردن User که واقعا مفید است بنویسید:
from django.contrib.auth.models import User
خب فکر کنم برای الان مدل ها بس باشه و اینکه برای اینکه با فیلد های بیشتری اشنا بشید گوگل فراموش نشه

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #4 : 05 مهر 1398، 12:02 ق‌ظ »
بسته هایی که استفاده کردم از این قرارن
پایتون ورژن 3.6.8
جنگو ۲.۲.۵
شاید بعدا از کتابخونه requests هم استفاده کردم

آفلاین esmaeelE

  • ناظر انجمن
  • *
  • ارسال: 1253
  • جنسیت : پسر
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #5 : 05 مهر 1398، 02:22 ق‌ظ »
بسته هایی که استفاده کردم از این قرارن
پایتون ورژن 3.6.8
جنگو ۲.۲.۵
شاید بعدا از کتابخونه requests هم استفاده کردم

خیلی خوبه
از این کتابخونه توی Web Scrapping هم استفاده می‌شه
ویکی نوشته 3.2 ورژن آخره

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #6 : 05 مهر 1398، 11:12 ق‌ظ »
بسته هایی که استفاده کردم از این قرارن
پایتون ورژن 3.6.8
جنگو ۲.۲.۵
شاید بعدا از کتابخونه requests هم استفاده کردم

خیلی خوبه
از این کتابخونه توی Web Scrapping هم استفاده می‌شه
ویکی نوشته 3.2 ورژن آخره
جنگو جدید ترین ورژنش ۲.۲.۵ خود داکیومنت های رسمی میگه

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #7 : 05 مهر 1398، 11:42 ق‌ظ »
خب میخوایم این دفعه یه ویو اولیه رو بنویسیم که همه ی سوالا رو در قالب یه جیسون برگردونه
خب برای نوشتن ویو ها به فایل views.py برید اونجا یه رندر رو ایمپورت کرده که بهش میرسیم پایینش جا برای ویوهاست
طبیعتا باید که این ویو ها یسری تابع باشن چون عمل پاسخ دادن سرور رو انجام میدن پس یه تابع تعریف میکنیم به اسم query_questions که میخواد همه ی سوالای توی دیتابیس رو نشون بده ولی قبل از نوشتن باید مدل هارو به دیتا بیس انتقال بدیم
python manage.py makemigrationspython manage.py migrateحالا به سراق ویو میریم خب اول باید همه ی سوالارو از دیتا بیس بخون پس کلاس سوال هارو از فایل models.py فراخوانی میکنیم سپس توی تابع یه متغیر به نام questions میسازیم که قراره سوالات توش ذخیره بشن خب مینویسیم:
questions=Question.objects.all()اسم Question همون مدل هست که فراخوانی شده متود objects برای گرفتن دیتا است سپس اینو با متود all() میگیریم که یعنی همه ی اشیا میشه از متد ها get() و filter() هم استفاده کرد اولی یه شرط میزاره مثلا میگیم فیلد فلانش برابر با فلان باشه:
q=Question.objects.get(text='this is a test')متود filter هم همین کارو میکنه منتهی فیلتر میتونه چندتا خروجی داشته باشه ولی get باید یک خروجی داشته باشه
خب حالا ما سوالاتو گرفتیم و توی یه متغیر ریختیم حالا باید به شکل جیسون برگردونیم
از اونجایی که یک دیکشنری نیست اول باید سریالایزش کتیم
برای این اول باید کتابخونه سریالایز رو فراخوانی کنیم:
from django.utils import serializersخب حالا یه متغیر تعریف میکنیم که این questions که سریالایز شده رو بریزیم توش بدین شکل مینویسیمش:
qserialized=serializers.serialize(questions)خب حالا باید برگردونیمش اول return میزاریم که ضروریه بعدش تابع JSONresponse رو فراخوانی میکنیم :
from django.http import JsonResponseو حالا جلو return تابع را میزاریم توش باید سه ارگومان بزاریم:
۱-باید که شی که میخوایم برگردانده بشه رو بزاریم که اینجا qserialized هستش
۲-حالا باید انکودر رو بزاریم که باید از کتابخونه پاییتونی جیسون فراخوانی بشه:
 from jsom import JSONencoderحالا مینویسیم در تابع که encoder=JSONencoder
۳-و ارگومان safe اگر یه شی سریالایز شده رو بخواهیم برگردونیم باید False باشه و اگر یک دیکشنری باشه True باشه که پیشفرض هست و در این حالت وارد نشه مهم نیستش
خب پس بخش برگردوندن شد:
return JsonResponse(qserialized,encoder=JSONencoder,safe=False)و در نهایت این ویوی کوچیک شدش :
def query_Questions(request):
    question=Question.objects.all()
    qserialized=serializers.serialize(question)
    return JsonResponse(qserialized,encoder=JSONencoder,safe=False)


نکته:همیشه باید به تابع یه شی request پاس داده بشه
خب حالا ویومون رو نوشتیم الان باید به url  ها اضافه بشه توی urls.py یه تابع url صدا میزنیم از:
from django.conf.urls import urlبعد یه url به شکل زیر توی لیست urlpatterns تعریف میکنیم
url(r'^questions/',views.query_question)که اولی یه ریجکسه که نشان دهنده ادرس تابع هستش یعنی اگه روی یه هاست ران بشه ادرس سایت رو بزنید بعد تو زیر ادرس /questions برید این تابع رخ میده
تابعی که رخ میده تابعیه که جلوشه
نکته:حتما views رو فراخوانی کنید

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #8 : 06 مهر 1398، 03:42 ب‌ظ »
سلام یخوام این دفعه توضیح بدم که چگونه اگر پارامتری ارسال شده در ریکویست بتونیم اونارو استخراج کنیم میخوایم جستوجوی سوال رو اضافه کنیم به پروژه:
اول از همه میایم یه تابع میسازیم توش اول نوع درخواست رو مشخص میکنیم چون پروتوکل http چند تا نوع درخواست داره ما از post , get استفاده میکنیم خب اول باید نوع رو مشخص کنیم
با شرط این کارو میکنیم:
if request.method =='GET':
بعد مابقی کار هارو زیر ایف مینویسم مال post هم همینطوره فقط با گت POST رو عوض میکنیم
حالا میخوایم که یک متغیر برای تکست تعیین کنیم که برابر با تمام سوالایی هستش که تکستشون برابر با تکستی است که کاربر به قالب پارامتر ریکویست میفرسته
خب این ورودی رو به اسم this_text ذخیره میکنیم:
this_text=request.GET['text']
خب پارامتر text که با گت ارسال شده ذخیره میشه توی یه متغیر حالا میایم با فیلتر ذخیره میکنیم و برمیگردونیم
خب این پست خیلی کوتاه شد پس رندر و اچ تی ام ال ریسپانس رو هم میگیم
خب طبیعتا یه فریمورک مثل جنگو فقط جیسون بر نمیگردونه بلکه http هم بر میگردونه خب برای اینکار دو روش هست روش اول اینه که خیلی راحت از همون جایی که تابع JsonResponse رو فراخوانی کردیم تابع HttpResponse رو هم فراخوانی کنیم بعد توش یه استرینگ برگردونیم که در واقع یه تیکه کد اچ تی ام ال است مثلا:
return HttpRespone('<h1>django is best freamwork</h1>')
ولی این خیلی چیز راحتی نیستش پس ما بر میداریم یه فایل برمیگردونیم با متود render که پیش فرض ایمپورت شده
ولی قبلش باید یه پوشه برای فایل های اچ تی ام ال پروژه درست کنیم و با سیستم وارد ارتباط کنیم برای این اول یه پوشه به نامه مثلا templates درست میکنیم هر جای پروژه میخوایم
بعد به فایل settings.py میریم اونجا توی لیست temp_dirs یا یه چیز شبیه این(دقیقا یادم نیستش ;D) اونجا ادرسش رو میزنیم مثلا 'templates/' که اینجا / روت پروژه است نه روت سیستم
بعد هر فایل اچ تی ام ال اون با اسم بدون ایمپورو این ادا اطفارو فراخوانی میشه توی متود render برای برگردوندن یه فایل اچ تی ام ال با متود render توی تابع با ورودی request(کلا تو همه ویو ها این ریکویستو بزارید باید حتما حتما):
return render(request,'index.html',{})
مشخصه که ریکویست رو وارد ارتباط با فایل اچ تی ام ال ارگومان دوم میکنه سومین ارگومانم مهم نیستش

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #9 : 07 مهر 1398، 05:13 ب‌ظ »
خب ما همیشه نمیخوایم از سرورمون اطلاعات بگیریم بعضی وقت ها نیازه که مردم اطلاعاتو به سرور بدن و سرور اونو تو دیتا بیس ذخیره کنه الان مثلا تو پروژه مون ما یه یوزر میخواید یه سوال تو دیتابیس زخیره که اینجا از متود create اسفاده میکنیم مثلا در قطعه کد زیر ما اطلاعاتو از پارامتر های ریکویست میگیرم و یه شی با استفاده از این متود ایجاد میکنیم:


text=request.GET['text']
User=request.GET['user']
question.objects.create(text=text,asker=User)
گرفتن پارامترو قبلا توضیح دادیم الان باید یه شی با استفاده از این پارامترا بسازیم که توی خط سوم بالا دیده میشود

خب پس ما از این متود با این ساختار پارامتر ها استفاده میکنیم تا یه ابژکت درست کنیم
خب الان یه کار دیگه انجام میدیم
میخوایم از پنل ادمین جنگو استفاده کنیم در ادرس localhost:8000/adminپنل ادمین وجود داره که با یه لاگین به عنوان ادمین میتوانید اونجا به شکل راحتی اشیا درست کنید واقعا کار راه اندازه
ولی قبلش باید دوتا کار بکنید :
اول باید برای پروژه تو یه ادمین درست کنید:
python manage.py createsuperuser
بعد از شما یوزر نیم پسورد و ایمیل میپرسه و بعد یه ادمین درست میشه که میتوانید باهاش تو پنل ادمین جنگو لوگین بکنید
یه مرحله دیگر شناسوندن مدل ها به ادمینه وارد فایل admin.py بشید اونجا بنویسید

admin.site.register(modelname)

به جای modelname نام مدلتونو بنویسید تا شناخته بشه

نکته:مدلتونو ایمپورت کنید

بعد خیلی خیلی راحت میتونید از توی ادمین مدل درست کنید

آفلاین ImTO1

  • Newbie
  • *
  • ارسال: 6
  • جنسیت : پسر
  • Live the moments
    • behmerd.ir
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #10 : 07 مهر 1398، 05:50 ب‌ظ »
بسیار عالی.
لطفا آموزش روادامه بدید.
foo ☕️ bar

آفلاین esmaeelE

  • ناظر انجمن
  • *
  • ارسال: 1253
  • جنسیت : پسر
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #11 : 07 مهر 1398، 06:14 ب‌ظ »
نصب django نسخه 3.1

پاک کردن تمام نسخه‌های قبلی
pip3 uninstall Djangopip uninstall Django
بعد از فعال کردن virtual environment  با دستور source .venv/bin/activate
به این ترتیب پیش می‌رویم.

دانلود
git clone https://github.com/django/django.git
نصب
cd django/
sudo python3 setup.py install
بررسی نسخه نصب شده

python3 -m django --version


در ضمن نسخه پیش فرض python درون virtual environment نسخه 2 هستش. (حداقل برای من که اینطور بوده)
باید ببینم چرا

which python
/home/ee/project-current/django/.venv/bin/python

python -V
Python 2.7.16


راه حل
نصب virtual env  با دستور زیر و پاک کردن قبلی
sudo apt remove virtualenv
sudo apt install python3-venv
و ساخت virtual env با دستور

python3 -m venv .venv
« آخرین ویرایش: 07 مهر 1398، 09:19 ب‌ظ توسط esmaeelE »

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #12 : 08 مهر 1398، 04:29 ب‌ظ »
نصب django نسخه 3.1

پاک کردن تمام نسخه‌های قبلی
pip3 uninstall Djangopip uninstall Django
بعد از فعال کردن virtual environment  با دستور source .venv/bin/activate
به این ترتیب پیش می‌رویم.

دانلود
git clone https://github.com/django/django.git
نصب
cd django/
sudo python3 setup.py install
بررسی نسخه نصب شده

python3 -m django --version


در ضمن نسخه پیش فرض python درون virtual environment نسخه 2 هستش. (حداقل برای من که اینطور بوده)
باید ببینم چرا

which python
/home/ee/project-current/django/.venv/bin/python

python -V
Python 2.7.16


راه حل
نصب virtual env  با دستور زیر و پاک کردن قبلی
sudo apt remove virtualenv
sudo apt install python3-venv
و ساخت virtual env با دستور

python3 -m venv .venv
برادر اون ۳.۱ نیست ۳.۰ هستش بعد  هم اینکه هنوز بتا است
نسخه با انتشار درست ۲.۲.۵ هستش یک ماه دیگه ۳.۰ منتشر میشه رسما

برای وبرچوال انو پایتون۳ هم ایننکه برای  همین ادرسو مشخص کردم با سوییچ -p

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #13 : 17 مهر 1398، 02:44 ب‌ظ »
خب یک اموزش مقدماتی خوب نوشتم که میشه باهاش یه شروع داشت ولی مطمینا حجم عظیمی از نکات رو نگفتم ولی دیگه سوادشو ندارم که اموزش بدم
به همین دلیل یکسری منابع معرفی میکنم تا با انها بتونید چیز های بیشتری یاد بگیرید و حرفه ای شوید
اولیش داکیومنت های رسمیه که کلا توی همه چیز داکیومنت ها بهترین چیز ها هستن:
https://docs.djangoproject.com/en/2.2/
یکی دیگه این کتابه که واقعا بهترین کتاب جنگو هستش :
https://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/0981467342
هر چند یک ذره ورژنش قدیمیه ولی باز هم مفیده
این هم کتاب خوبیه به نظرم:
https://www.amazon.com/dp/1081582162/?tag=mlinar-20
و اموزش ویدیویی هم این خوبه:
https://www.youtube.com/watch?v=F5mRW0jo-U4

آفلاین هومان

  • High Hero Member
  • *
  • ارسال: 1527
  • جنسیت : پسر
  • آرچ + گنوم
پاسخ : با هم جنگو یاد بگیریم
« پاسخ #14 : 06 آذر 1398، 05:45 ب‌ظ »
شروع به ضبط دوره ویدیویی جنگو کردم
قسمت اول اضافه شد:
https://www.aparat.com/v/mD1f6