# **Section 1: Welcome to Try Django**
Jika kita mengirim request ke sebuah website, website tersebut akan mengembalikan sekumpulan kode yang bisa dipahami oleh browser kita. Django adalah web framework berbasis Python. Karena berbasis Python, Django lebih mudah untuk dipahami dibanding dengan framework lainnya. Django bisa dipakai untuk membangun e-commerce, membuat algoritma, dll.
Django memungkinkan web developer untuk membangun website yang dinamis dengan mengatur respons terhadap permintaan URL, mengingat informasi pengguna, dan membagi fungsionalitas ke dalam komponen yang terpisah yang disebut "apps".

Django didasarkan pada arsitektur MVT (Model-View-Template) yang memiliki tiga bagian berikut:
* **Model:** Model akan bertindak sebagai interface data anda yang bertanggung jawab untuk mempertahankan data. Model adalah struktur logical data di balik seluruh aplikasi dan direpresentasikan oleh database (umumnya database relasional seperti MySql, Postgres).
* **View:** View adalah interface pengguna yang Anda lihat di browser Anda saat Anda merender sebuah situs web. View direpresentasikan oleh file HTML/CSS/Javascript.
* **Template:** Sebuah template terdiri dari bagian static output HTML serta beberapa sintaks khusus yang menjelaskan bagaimana konten dinamis akan dimasukkan.
## **1. Instalasi dan Mencoba Django**
[Referensi mencoba Django](https://www.codingforentrepreneurs.com/blog/create-a-blank-django-project/)
1. Clone repositori

2. Buat file .env di src/ (Untuk yang menggunakan VM tambahkan ip lokal vm di ALLOWED_HOST)

3. Gunakan Docker Compose untuk postgres dan redis
```
docker compose -f docker-compose.dev.yaml up -d
```

4. Build image yang sudah dibuat di Dockerfile
```
docker build -t cfe-blank-project .
```

5. Jalankan container
```
docker run -d --name cfe-blank-project --network cfe_blank_network -p 8000:8000 -e PORT=8000 --env-file src/.env cfe-blank-project
```

6. Install requirement (di dalam container)
```
python -m pip install -r src/requirements.txt
```

7. Tes browsing

## **2. Membuat Setting Module**
Fungsi dari membuat setting module baru adalah agar terdapat dua settings. Yang pertama local setting untuk melakukan test atau development, yang kedua live setting untuk server
1. Ubah nama settings.py untuk membedakan kedua settings
```
mv settings.py old_settings.py
```

2. Buat folder settings, buat file innit dan buat file untuk module lain
```
mkdir settings && cd settings
touch __init__.py
touch production.py
touch local.py
```
3. buat file base.py yang berisikan isi old_settings.py (lakukan hal yang sama ke production.py dan local.py)
```
nano base.py
```

4. di base.py ubah (lakukan hal yang sama ke production.py dan local.py)
```
BASE_DIR = Path(__file__).resolve().parent.parent
# jadi
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# dan
from .db import *
# jadi
from ..db import *
```
5. import base.py dan module lain di file innit
```
nano __init__.py
```

6. Jalankan container dan tes browsing
```
docker run -d --name cfe-blank-project -v src/ --network cfe_blank_network -p 8000:8000 -e PORT=8000 --env-file src/.env cfe-blank-project
```

# **Section 2: HTML dan Django**
## **1. Rendering HTML**
1. di folder /src jalankan command startapp
```
python manage.py startapp netdev
cd netdev/
```

2. Masukkan html di views.py
```
nano views.py
```

3. Masukkan app views yang dibuat ke url
```
nano urls.py
```

4. Tes browsing

## **2. Render a Django Template**
Template digunakan untuk merender tampilan halaman web. Template adalah file yang HTML dengan kode Python di dalamnya untuk melakukan logika.
1. Di setting base.py tambahkan direktori di templates
```
nano base.py
```

2. Buat folder templates yang berisi base.html
```
mkdir templates && cd templates
nano base.html
```

3. Ke views.py, return request home ke template yang dibuat

4. Tes browsing

## **3. Context in Django Template**
Kita bisa menggunakan context variables di django untuk menambahkan python dictionary ke dalam templates
1. Tambahkan beberapa variabel di views.py
```
nano netdev/views.py
```

2. Implementasikan variabel tersebut ke template
```
nano templates/base.html
```

3. Tes browsing

## **4. Template Inheritance**
Template Inheritance pada django digunakan supaya tidak mengulang codingan yang sama, seperti header atau footer.
1. Import beberapa views dan tambahkan beberapa url
```
nano cfehome/urls.py
```

2. Masukkan html ke views
```
nano netdev/views.py
```

3. Ubah base.html agar menjadi parent
```
nano templates/base.html
```

4. Sesuaikan template lain
**home.html**

**about.html**

**contact.html**

5. Tes browsing
**Home**

**About**

**Contact**

## **5. Include Template Tag**
Berbeda dengan Template view, Template tag hanya sekumpulan kode saja bukan full template
1. Buat folder snippets di dalam folder templates dan buat nav.html
```
mkdir templates/snippets
nano templates/snippets/nav.html
```

2. Sesuaikan base.html
```
nano templates/base.html
```

3. Tes browsing

## **6. Class Based View dan Template View**
Class digunakan untuk menghindari pembuatan fungsi yang berulang
1. Tambah Template View untuk home.html di views.py
```
nano netdev/views.py
```

2. Tambah Template View untuk about dan contact di urls.py
```
nano cfehome/urls.py
```

# **Section 3: Remembering Things**
## **1. Models**
1. Tambahkan superuser
```
python manage.py createsuperuser
```

2. Buat class di models.py
```
nano netdev/models.py
```

3. Tambahkan apps ke dalam INSTALLED_APPS di setting
```
nano cfehome/settings/base.py
```

4. Lakukan migrasi
```
python manage.py makemigrations
python manage.py migrate
```

5. Import model yang dibuat ke admin.py
```
nano netdev/admin.py
```

6. Periksa di page admin

7. Untuk menambahkan data, klik add

8. Periksa data yang dibuat

## **2. Displaying Saved Data**
1. Buat template baru untuk menampilkan data
nano templates/restaurant.html

2. Buat function untuk mengembalikan html yang dibuat
```
nano netdev/views.py
```

3. Import ke dalam urls.py
```
nano cfehome/urls.py
```

4. Tes browsing

## **3. Generic List View**
1. Tambah class baru yang menggunakan list view di views.py
```
nano netdev/views.py
```

2. Tambahkan url baru di urls.py
```
nano cfehome/urls.py
```

3. Tes Browsing
**restaurant**

**restaurant/warteg**

**restaurant/padang**

## **4. Profile Detail**
1. Tambah class baru yang menggunakan detail view di views.py
```
nano netdev/views.py
```

2. Tambahkan url baru di urls.py
```
nano cfehome/urls.py
```

3. Buat HTML untuk menampilkan detail view
```
nano templates/restaurant_detail.html
```

4. Tes Browsing



## **5. Unique Slug dan Signal**
1. Buat unique slug generator
```
nano netdev/utils.py
```

3. Tambahkan signal di models.py
```
nano netdev/models.py
```

4. Uji coba


# **Section 4: Forms, Views, Models, and More**
## **1. Membuat Slugs sebagai URL Parameter**
Slug bertujuan untuk membuat URL menjadi user friendly dengan penggunaan regular expressions. Setelah slug dibuat, kita dapat membuat URL dengan slug yang sesuai. Hal ini membuat navigasi pengguna menjadi lebih mudah dan lebih intuitif.
1. Ubah url detail view ke parameter slug
```
nano cfehome/urls.py
```

2. Hapus fungsi get_object di class DetailView
```
nano netdev/views.py
```

3. Tambah link di list view
```

```

4. Tes Browsing
**List view**

**Klik link 'Domino's Pizza'**

## **2. Menyimpan Data Menggunakan Django Form**
Penggunaan form dalam Django memiliki beberapa keunggulan, salah satunya adalah kemampuan untuk melakukan validasi data dengan mudah. Form validation memungkinkan kita untuk menentukan aturan validasi khusus untuk setiap bidang dalam form. Hal tersebut bertjuan agar user menginput data sesuai dengan aturan. Selain itu, penggunaan Django form juga dapat menampilkan kesalahan secara otomatis.
### **2.1. Django Form dengan Function Based View**
1. Tambahkan form di urls.py
```
nano cfehome/urls.py
```

2. Buat class forms
```
nano netdev/forms.py
```

3. Import forms ke view.py
```
nano netdev/views.py
```

4. Buat html forms
```
nano templates/netdev/form.html
```

5. Tes Browsing


### **2.2. Django Form dengan Class Based View (Create View)**
1. Tambah class create view
```
nano netdev/views.py
```

2. tambah class form baru
```
nano netdev/forms.py
```

3. Ganti urlnya
```
nano cfehome/urls.py
```

4. Tes browsing

## **3. Validation**
Validator ini memungkinkan developer untuk memastikan bahwa data yang dimasukkan oleh pengguna sesuai dengan aturan, sebelum disimpan ke dalam database.
1. Buat validators
```
nano netdev/validators.py
```

2. import validator di forms.py dan models.py
```
nano netdev/forms.py
nano netdev/models.py
```


3. Tes Browsing

## **4. Kepemilikan Data**
Penggunaan ForeignKey dapat memberikan kepemilikan data kepada user. Dengan menambahkan ForeignKey ke sebuah model, setiap instance dari model tersebut menjadi terkait dengan user tertentu. Hal ini memungkinkan user hanya dapat mengakses, mengedit, atau menghapus data yang mereka miliki sendiri. Selain itu, validasi akses pengguna juga diperlukan untuk memastikan bahwa pengguna hanya dapat mengakses data yang diizinkan sesuai dengan role mereka.
1. Tambahkan foreign key user di models
```
nano netdev/models.py
```

2. Migrasi data
```
python manage.py makemigrations
python manage.py migrate
```

3. Implementasikan FK owner ke forms dan page redirect ke login
```
nano netdev/views.py
```

4. Buat class untuk LoginView di views.py
```
nano netdev/views.py
```

5. Tambah LoginView di urls.py
```
nano cfehome/urls.py
```

6. Buat templatenya
```
mkdir templates/registration/
nano templates/registration/login.html
```

7. Tes
**Buat user baru**

**Login menggunakan user baru**

**Buat data**

**Cek kepemilikan**

## **5. Menggunakan reverse**
Penggunaan reverse berguna untuk menghasilkan URL secara dinamis. Dengan menggunakan fungsi reverse, kita dapat menghasilkan URL berdasarkan nama URL dan argumen tertentu yang diperlukan.
1. Beri nama di urls.py
```
nano cfehome/urls.py
```

2. reverse url untuk detail view
```
nano netdev/models.py
nano templates/netdev/restaurant_list.html
```


3. Tambahkan urls.py di apps
```
nano netdev/urls.py
```

4. Update nav.html
```
nano templates/snippets/nav.html
```

## **6. Membuat Menu App**
1. Buat app menu
```
python manage.py startapp menus
```
2. buat class item
```
nano menus/models.py
```

3. Lakukan migrasi
```
python manage.py makemigrations
python manage.py migrate
```

4. Tambahkan class di admin.py
```
nano menus/admin.py
```

5. Periksa di admin page

6. Buat views.py
```
nano menus/views.py
```

7. Buat forms.py
```
nano menus/forms.py
```

8. Buat urls.py
```
nano menus/urls.py
```

9. Tambah urls menu ke urls.py utama
```
nano cfehome/urls.py
```

10. Buat templatenya
```
mkdir menus/templates
nano menus/templates/item-detail.html
nano menus/templates/item-list.html
```


11. Tes browsing
**Isi item menggunakan forms**

**item detail view**

**item list view**

## **7. Membatasi form berdasarkan kepemilikan**
Membatasi akses pengguna terhadap data dapat membantu meningkatkan keamanan dan fungsionalitas aplikasi web dengan memastikan bahwa pengguna hanya dapat mengakses dan mengelola data yang sesuai dengan hak akses mereka.
1. Tambahkan fungsi di form agar hanya mengambil sesuai kepemilikan
```
nano menus/forms.py
```

2. Update CreateView dan UpdateView agar menampilkan data sesuai kepemilikan
```
nano menus/views.py
```

3. Tambahkan url update
```
nano menus/urls.py
```

4. Tes browsing
**page item create dengan user 'admin'**

**page item create dengan user 'alvan'**

## **8. Personalize items**
1. Sesuaikan views di restaurants
```
nano netdev/views.py
```

2. Ubah urls restoran
```
nano netdev/urls.py
```

3. Buat html untuk update detail view restoran
```
nano templates/netdev/detail_update.html
```

4. Buat form snippet
```
nano templates/snippets/form-snippet.html
```

5. Sesuaikan templates restoran
```
nano templates/netdev/restaurant_list.html
```

6. Tes browsing
**page list view dengan user 'admin'**

**page list view dengan user 'alvan'**

**Tampilan detail update view**

## **9. User Profile View**
1. Buat app baru untuk profile
```
python manage.py startapp profiles
```

2. Tambah ProfileDetailView di views.py
```
nano profiles/views.py
```

3. tambah urls.py di app profile
```
nano profiles/urls.py
```

4. Tambah urlnya ke app utama
```
nano cfehome/urls.py
```

5. Buat templatenya
```
mkdir profiles/templates/
mkdir profiles/templates/profiles
nano profiles/templates/profiles/user.html
```

6. Tambah app ke settings.py
```
nano cfehome/settings/base.py
```

7. Tes browsing
**User 'alvan'**

**User 'admin'**

## **10. Search**
1. Tambahkan function get_context_data di views profile
```
nano profiles/views.py
```

2. Ubah template profile
```
nano profiles/templates/profiles/user.html
```

3. Tambahkan class untuk mencari
```
nano netdev/models.py
```

4. Tes browsing
**Search keyword 'Ayam'**

**Seach keyword 'Sukabirus'**

# **Section 5: Handling User and Followers**
## **1. Follow system**
1. Tambah models untuk profile app
```
nano profiles/models.py
```

2. Tambahkan data ke admin.py
```
nano profiles/admin.py
```

3. Migrasi data
```
python manage.py makemigrations
python manage.py migrate
```

## **2. Follow Toggle Button dan Follow Feed**
1. Tambah URL profile follow toggle
```
nano cfehome/urls.py
```

2. Buat class untuk follow toggle dan tambahkan context baru
```
nano profiles/views.py
```


3. Buat snippet tombol follow dan tambahkan snippetnya ke templat user
```
mkdir profiles/templates/snippets
nano profiles/templates/snippets/follow_form.html
nano profiles/templates/profiles/user.html
```


4. Masukkan logic ke models.py
```
nano profiles/models.py
```

5. Buat view untuk menampilkan daftar menu yang difollow
```
nano menus/views.py
```

6. Buat templatenya
```
nano menus/templates/menus/home-feed.html
```

7. Tes browsing
**User sebelum difollow**

**User sesudah difollow**

**Tampilan homepage**

## **3. Register View**
1. Buat form untuk register
```
nano profiles/forms.py
```

2. Buat viewnya
```
nano profiles/views.py
```

3. Tambah urlnya
```
nano cfehome/urls.py
```

4. Buat templatenya
```
nano templates/registration/register.html
```

5. Tes browsing
**Lakukan register**

**Cek di database**

## **4. Activation Keys**
1. Buat logic mengirim Activation Keys lewat email
```
nano profiles/models.py
```

2. Buat code generator
```
nano profiles/utils.py
```

3. Migrasi data
```
python manage.py makemigrations
python manage.py migrate
```

4. Tambah email ke settings untuk mengirim email
```
nano cfehome/settings/base.py
```

5. Tambahkan view untuk aktivasi user
```
nano profiles/views.py
```

6. Tambah URL untuk aktivasi
```
nano cfehome/urls.py
```

7. Tes browsing
**Register akun baru**

**Lihat activation key-nya**

**Masukkan url**
