Skip to content

Commit

Permalink
selesai tutor 2
Browse files Browse the repository at this point in the history
  • Loading branch information
fathonidf committed Sep 19, 2023
1 parent 9c9c06b commit b38a895
Show file tree
Hide file tree
Showing 14 changed files with 286 additions and 17 deletions.
32 changes: 32 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
**/*.pyc
**/*.pyo
**/*.mo
**/*.db
**/*.css.map
**/*.egg-info
**/*.sql.gz
**/__pycache__/
.cache
.project
.idea
.pydevproject
.idea/workspace.xml
.DS_Store
.git/
.sass-cache
.vagrant/
dist
docs
env
logs
src/{{ project_name }}/settings/local.py
src/node_modules
web/media
web/static/CACHE
stats
Dockerfile
.gitignore
Dockerfile
db.sqlite3
**/*.md
logs/
24 changes: 24 additions & 0 deletions .github/workflows/pbp-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Deploy

on:
push:
branches:
- main
- master

jobs:
Deployment:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Cloning repo
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Push to Dokku server
uses: dokku/github-action@master
with:
branch: 'main'
git_remote_url: ssh://dokku@${{ secrets.DOKKU_SERVER_IP }}/${{ secrets.DOKKU_APP_NAME }}
ssh_private_key: ${{ secrets.DOKKU_SSH_PRIVATE_KEY }}
32 changes: 32 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
FROM python:3.10-slim-buster

WORKDIR /app

ENV PYTHONUNBUFFERED=1 \
PYTHONPATH=/app \
DJANGO_SETTINGS_MODULE=shopping_list.settings \
PORT=8000 \
WEB_CONCURRENCY=2

# Install system packages required Django.
RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*

RUN addgroup --system django \
&& adduser --system --ingroup django django

# Requirements are installed here to ensure they will be cached.
COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt

# Copy project code
COPY . .

RUN python manage.py collectstatic --noinput --clear

# Run as non-root user
RUN chown -R django:django /app
USER django

# Run application
# CMD gunicorn shopping_list.wsgi:application
2 changes: 2 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
release: django-admin migrate --noinput
web: gunicorn adventurers_inventory.wsgi
47 changes: 42 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ PBP E`
[Link to Adventurer's Inventory](https://adventurers-inventory.adaptable.app/main)

## Tugas 2
>1. Jelaskan bagaimana cara kamu mengimplementasikan checklist di atas secara step-by-step (bukan hanya sekadar mengikuti tutorial).
<details>
<summary>1. Jelaskan bagaimana cara kamu mengimplementasikan checklist di atas secara step-by-step (bukan hanya sekadar mengikuti tutorial).</summary>

- [x] Membuat sebuah proyek Django baru.

Expand Down Expand Up @@ -113,14 +114,18 @@ Pada PBP sekarang, kepentingan *deployment* bertujuan untuk menampilkan secara l

Terakhir, aplikasi yang saya buat memiliki *domain* bernama `https://adventurers-inventory.adaptable.app/main`.

</details>

>2. Buatlah bagan yang berisi request client ke web aplikasi berbasis Django beserta responnya dan jelaskan pada bagan tersebut kaitan antara urls.py, views.py, models.py, dan berkas html.
<details>
<summary>2. Buatlah bagan yang berisi request client ke web aplikasi berbasis Django beserta responnya dan jelaskan pada bagan tersebut kaitan antara urls.py, views.py, models.py, dan berkas html.</summary>

![bagan](https://github.com/fathonidf/adventurers-inventory/assets/105644250/9cb5536b-83d7-45ea-ae2b-a8abde7cde9e)

Saat pengguna mengirimkan permintaan HTTP aplikasi main melalui web browser, urls.py melakukan pemetaan URL untuk meneruskan permintaan HTTP ke views.py sesuai dengan URL yang diminta. Kemudian, view menghasilkan response HTTP berupa halaman HTML. Dalam proses ini, views.py mengambil data yang diperlukan melalui models.py dan menampilkan data tersebut menggunakan template main.html.
</details>

>3. Jelaskan mengapa kita menggunakan virtual environment? Apakah kita tetap dapat membuat aplikasi web berbasis Django tanpa menggunakan virtual environment?
<details>
<summary>3. Jelaskan mengapa kita menggunakan virtual environment? Apakah kita tetap dapat membuat aplikasi web berbasis Django tanpa menggunakan virtual environment?</summary>

Virtual environment digunakan untuk mengisolasi *dependencies* dan modul Python yang dipakai untuk kebutuhan proyek Anda masing-masing sehingga tidak akan bertabrakan dan terpengaruh oleh modul atau konfigurasi proyek yang lain. Hal ini akan menghindari instalasi paket atau modul secara global karena semisal paket atau modul tersebut hanya untuk proyek tertentu.

Expand All @@ -129,8 +134,10 @@ Semisal Proyek A menggunakan Django 4.0 dan Proyek B menggunakan Django 4.1, den
Virtual environment dibuat dengan perintah `python -m venv env`, dan diaktifkan dengan perintah `env\Scripts\activate.bat`.

Membuat aplikasi tanpa *virtual environment* tetap dapat dijalankan namun lebih dianjurkan mengimplementasikan *virtual environment* karena hal ini dapat memudahkan untuk pengelolaan konsistensi dari masing-masing *dependencies* proyek sehingga menjadikannya sebuah *good practice*
</details>

>4. Jelaskan apakah itu MVC, MVT, MVVM dan perbedaan dari ketiganya.
<details>
<summary>4. Jelaskan apakah itu MVC, MVT, MVVM dan perbedaan dari ketiganya.</summary>

| MVC | MVT | MVVM |
| --- | ---- | --- |
Expand All @@ -139,4 +146,34 @@ Membuat aplikasi tanpa *virtual environment* tetap dapat dijalankan namun lebih
| View: Bertanggung jawab sebagai pengelola antarmuka pengguna dan menampilkan data yang diberikan model lalu mengirim input ke Controller | View: Visualisasi dan menampilkan data ke pengguna tetapi dalam Framework Python Django| View: Menginformasi ke ViewModel terkait interaksi pengguna, dan hanya menampilkan data yang disediakan oleh ViewModel |
| Controller: Menjembatani hubungan antara View dan Model dan sebagai inti logika dan alur aplikasi dengan menginformasi interaksi user ke Model | Template: Mengambil data dari model dan menampilkannya, berupa HTML | ViewModel: Perantara antara Model dan View, mengubah data dari Model menjadi format sesuai dengan tampilan |
|![mvc](https://media.geeksforgeeks.org/wp-content/uploads/20201002214740/MVCSchema.png) |![mvp](https://media.geeksforgeeks.org/wp-content/uploads/20201024233154/MVPSchema.png) |![mvvm](https://media.geeksforgeeks.org/wp-content/uploads/20201002215007/MVVMSchema.png) |
|MVC adalah pola yang umum digunakan dalam pengembangan aplikasi berbasis desktop dan web tradisional. Ini memisahkan tiga komponen utama aplikasi untuk meningkatkan pemeliharaan dan pengembangan kode. |MVT adalah pola yang spesifik untuk kerangka kerja Django, yang dirancang khusus untuk pengembangan aplikasi web dengan Python. Ini menggantikan View dalam MVC dengan Template, yang memungkinkan pemisahan yang lebih jelas antara tampilan dan pemrosesan HTTP. |MVVM adalah pola desain yang sering digunakan dalam pengembangan aplikasi berbasis antarmuka pengguna (UI), terutama pada platform seperti WPF (Windows Presentation Foundation). Ini fokus pada pemisahan antara tampilan dan logika bisnis, dengan menggunakan ViewModel sebagai perantara. |
|MVC adalah pola yang umum digunakan dalam pengembangan aplikasi berbasis desktop dan web tradisional. Ini memisahkan tiga komponen utama aplikasi untuk meningkatkan pemeliharaan dan pengembangan kode. |MVT adalah pola yang spesifik untuk kerangka kerja Django, yang dirancang khusus untuk pengembangan aplikasi web dengan Python. Ini menggantikan View dalam MVC dengan Template, yang memungkinkan pemisahan yang lebih jelas antara tampilan dan pemrosesan HTTP. |MVVM adalah pola desain yang sering digunakan dalam pengembangan aplikasi berbasis antarmuka pengguna (UI), terutama pada platform seperti WPF (Windows Presentation Foundation). Ini fokus pada pemisahan antara tampilan dan logika bisnis, dengan menggunakan ViewModel sebagai perantara. |

</details>

---
## Tugas 3

<details>
<summary>1. Apa perbedaan antara form POST dan form GET dalam Django?</summary>

</details>

<details>
<summary>2. Apa perbedaan utama antara XML, JSON, dan HTML dalam konteks pengiriman data?</summary>

</details>

<details>
<summary>3. Mengapa JSON sering digunakan dalam pertukaran data antara aplikasi web modern?</summary>

</details>

<details>
<summary>4. Jelaskan bagaimana cara kamu mengimplementasikan checklist di atas secara step-by-step (bukan hanya sekadar mengikuti tutorial).</summary>

</details>

<details>
<summary>Screenshot Postman</summary>

</details>
18 changes: 17 additions & 1 deletion adventurers_inventory/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,24 @@
"""

from pathlib import Path
import environ
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

env = environ.Env()

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-^_h^l&&h_)%-e(+^^bj%8#pk$4wpm0#*wb!0)=a^z260m0f8+3'

# Automatically determine environment by detecting if DATABASE_URL variable.
# DATABASE_URL is provided by Heroku if a database add-on is added (e.g. Heroku Postgres).
PRODUCTION = env.bool('PRODUCTION', False)

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

Expand Down Expand Up @@ -55,7 +62,7 @@
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
Expand All @@ -81,6 +88,13 @@
}
}

# Set database settings automatically using DATABASE_URL.
if PRODUCTION:
DATABASES = {
'default': env.db('DATABASE_URL')
}
DATABASES["default"]["ATOMIC_REQUESTS"] = True


# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
Expand Down Expand Up @@ -118,6 +132,8 @@

STATIC_URL = 'static/'

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

Expand Down
2 changes: 1 addition & 1 deletion adventurers_inventory/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@

urlpatterns = [
path('admin/', admin.site.urls),
path('main/', include('main.urls'))
path('', include('main.urls'))
]
7 changes: 7 additions & 0 deletions main/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.forms import ModelForm
from main.models import Item

class ItemForm(ModelForm):
class Meta:
model = Item
fields = ["name", "amount", "description", "price", "item_level", "use"]
19 changes: 19 additions & 0 deletions main/templates/create_item.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% extends 'base.html' %}

{% block content %}
<h1>Add New Item</h1>

<form method="POST">
{% csrf_token %}
<table>
{{ form.as_table }}
<tr>
<td></td>
<td>
<input type="submit" value="Add Item"/>
</td>
</tr>
</table>
</form>

{% endblock %}
48 changes: 43 additions & 5 deletions main/templates/main.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
<h1>{{app_name}}</h1>
{% extends 'base.html' %}

<h5>Nama: </h5>
<p>{{ name }}</p> <!-- Ubahlah sesuai dengan nama kamu -->
<h5>Kelas: </h5>
<p>{{ class }} </p> <!-- Ubahlah sesuai dengan kelas kamu -->
{% block content %}
<h1>{{app_name}}</h1>

<h5>Name:</h5>
<p>{{name}}</p>

<h5>Class:</h5>
<p>{{class}}</p>

<table>
<tr>
<th>Name</th>
<th>Amount</th>
<th>Description</th>
<th>Price</th>
<th>iLvl</th>
<th>Use</th>
</tr>

{% comment %} Berikut cara memperlihatkan data produk di bawah baris ini {% endcomment %}

{% for product in products %}
<tr>
<td>{{product.name}}</td>
<td>{{product.amount}}</td>
<td>{{product.description}}</td>
<td>{{product.price}}</td>
<td>{{product.item_level}}</td>
<td>{{product.use}}</td>
</tr>
{% endfor %}
</table>

<br />

<a href="{% url 'main:create_item' %}">
<button>
Add New Item
</button>
</a>

{% endblock content %}
12 changes: 10 additions & 2 deletions main/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
from django.urls import path, include
from main.views import show_main
from main.views import show_main, create_item, show_xml, show_json, show_xml_by_id, show_json_by_id




app_name = 'main'

urlpatterns = [
path('', show_main, name='show_main')
path('', show_main, name='show_main'),
path('create-item', create_item, name='create_item'),
path('xml/', show_xml, name='show_xml'),
path('json/', show_json, name='show_json'),
path('xml/<int:id>/', show_xml_by_id, name='show_xml_by_id'),
path('json/<int:id>/', show_json_by_id, name='show_json_by_id')
]
39 changes: 37 additions & 2 deletions main/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
from django.shortcuts import render
from django.http import HttpResponseRedirect
from main.forms import ItemForm
from django.urls import reverse
from main.models import Item
from django.http import HttpResponse
from django.core import serializers

# Create your views here.
def show_main(request):
item = Item.objects.all()

context = {
'app_name': 'Adventurer\'s Inventory',
'name': 'Daffa Mohamad Fathoni',
'class': 'PBP E'
'class': 'PBP E',
'Item': item
}

return render(request, "main.html", context)
return render(request, "main.html", context)

def create_item(request):
form = ItemForm(request.POST or None)

if form.is_valid() and request.method == "POST":
form.save()
return HttpResponseRedirect(reverse('main:show_main'))

context = {'form': form}
return render(request, "create_item.html", context)

def show_xml(request):
data = Item.objects.all()
return HttpResponse(serializers.serialize("xml", data), content_type="application/xml")

def show_json(request):
data = Item.objects.all()
return HttpResponse(serializers.serialize("json", data), content_type="application/json")

def show_xml_by_id(request, id):
data = Item.objects.filter(pk=id)
return HttpResponse(serializers.serialize("xml", data), content_type="application/xml")

def show_json_by_id(request, id):
data = Item.objects.filter(pk=id)
return HttpResponse(serializers.serialize("json", data), content_type="application/json")
Loading

0 comments on commit b38a895

Please sign in to comment.