Language:

Search

Tutorial Django di Windows Lengkap Dengan Contoh Kasus [3]

  • Share this:
post-title

Register App 

Sekarang kita akan utak-atik bagian lain, yaitu login dan registrasinya, kita buat apps baru 
yang dinamakan accounts, lalu jangan lupa register in di settings.py terus buat urls.py yang di core 
lalu buat model dan views nya, oh iya kali ini kita bikin direktori khusus 
untuk file html daripada apps accounts ini sendiri begitu ya, tapi inget, tetep bikinnya di direktori templates
bikin sendiri hayoooo coba latian untuk register di settings.py urls.py di core dan function di views.py 

tapi ini yang urls.py nya di apps account saya kasih bocoran aja, karena 
kurang lebih nanti url nya akan begini localhost:8000/accounts/login
yang ternyata nanti ada pilihan login,register,logout dan dashboard tampilan dari sisi user 
jadinya kita buat begini...

.....
urlpatterns = [
    path('login', views.login, name='login'),
    path('register', views.register, name='register'),
    path('logout', views.logout, name='logout'),
    path('dashboard', views.dashboard, name='dashboard'),
]
.....

untuk di views.py khusus function logout nya, di import path nya itu kita tambahkan redirect 
jadinya 
def logout(request):
    return redirect('home')
    
Setelah itu jangan lupa di templates/includes terus yang di dalam-dalamnya 
saat ada link login dan register, di ganti pakai url ya, udah bisa lah pasti...

Sekarang kita ambil source html dari file login.html yang jelas isi dulu ya 
extends block dll seperti biasa ambil dari class sub-banner, lalu dibawahnya lagi ada 
content-section, ambil 1 div itu paste di bawahnya sub-banner tadi ya, lalu atur semua static nya

Begitupun yang di register ambil dari file signup.html dan file dashboard.html juga, seharusnya udah tau lah ya...
Sekarang kita mulai di register, kita pasang csrf token, mulai dengan form action yang method GET ganti jadi POST
lalu dibawah form action itu, kasih {% csrf_token %} lalu apa sih gunanya csrf_token ?
gunanya untuk mengecek setiap user yang mengakses website
token ini akan digunakan untuk memverifikasi apakah user tersebut yang meminta token
karena prosesnya biasanya user atau pengunjung website dapat token
lalu user akan memasukkan di field terhadap form yang memiliki method POST 
dalam hal ini form tadi ya. Lalu token ini akan memastikan lagi 
samakah token yang dikirim dengan token yang diminta oleh user tadi?
Lakukan hal yang sama untuk login.html ya

Setelah itu kita ke views.py nya accounts ya, kita buat supaya beneran bisa di pake daftar 
di function register di atas return tambahkan kode 

    if request.method == 'POST':
        print('Bisa')
        return redirect('register')
    else:
        
Di else nya kita kasih return render ya...

Kali ini kita belajar tentang Django Messages sekalian belajar baca dokumentasi ya...
jadi Django Messages ini framework juga yang gunanya akan ngasih pesan di web 
seperti pesan error, warning message dan lain-lain 

kalau kita baca https://docs.djangoproject.com/en/3.2/ref/contrib/messages/  
dimana message ini akan di implementasi di middleware
sebelum itu kita ambil dulu 
from django.contrib.messages import constants as messages
MESSAGE_TAGS = {
    messages.ERROR: 'danger',
}
Tapi kita hapus aja key dan value 50: dan yang INFO ganti dengan ERROR
setelah itu di templates/includes kita bikin messages.html
di dalamnya kita kasih 

{% if messages %}
    {% for message in messages %}
        <div id="message" class="container">
            <div class="alert alert-{{ message.tags }}" alert-dismissable-role="alert">
                <button type="button" class="close" data-dismiss="alert"><span arial-hidden="true">&times;</span></button>
                
                <strong>
                {% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
                    Error:
                {% else %}
                    {{message.tags|title}}
                {% endif %}
                </strong>
                {{message}}
            </div>
        </div>
    {% endfor %}
{% endif %}

Jadi skenarionya tadi kan pakai django messages sudah di masukkin di settingsnya
terus atribut nya bisa di pakai di file html sebagai pesan error, nah nanti setiap ada pesan error 
akan di tampilkan dengan isi yang barusan kita buat ini.

Sekarang balik lagi ke views.py di function register, kita impor dulu 
from django.contrib import messages
lalu kita edit yang di bawah if
message.error(request, 'Eror bro')

Oh iya di folder root lalu di static/js/apps.js tambahkan di paling bawah 

setTimeout(function(){
  $('#message').fadeOut('slow')
})

Terus di register.html nya tepat dibawah create an account</h3>
kita kasih {% include 'includes/messages.html' %}
supaya file message.html nya bisa di pakai, jadi kalau kita isi asal-asalan 
di register hasilnya seperti ini 

Sekarang kita akan buat username di form registration menjadi unique, yang dimaksud adalah 
jika username sudah ada, maka proses registrasi tidak akan di proses,jadi hampir semua form nya 
ada sistem validasinya, oke kita mulai dengan views.py di function register 
kita ubah di bawah if, kita isi dengan 

    if request.method == 'POST':
        firstname = request.POST['firstname']
        lastname = request.POST['lastname']
        username = request.POST['username']
        email = request.POST['email']
        password = request.POST['password']
        confirm_password = request.POST['confirm_password']
        if password == confirm_password:
            if User.objects.filter(username=username).exists():
                messages.error(request, 'Username sudah ada')
                return redirect('register')
            else:
                if User.objects.filter(email=email).exists():
                    messages.error(request, 'Email sudah ada ')
                    return redirect('register')
                else:
                    user = User.objects.create_user(first_name=firstname, last_name=lastname, email=email, username=username, password=password)
                    auth.login(request, user)
                    messages.success(request, 'sudah login')
                    return redirect('dashboard')
                    user.save()
                    messages.success(request, 'Akunmu sudah terdaftar')
                    return redirect('login')
        else:
            messages.error(request, 'Password gak sama')
    else:
        return render(request, 'accounts/register.html')

        
Itu semua kita ganti sampai di else return ya...
Jadi penjelasan sederhana dari codingan diatas adalah
pertama impor dulu from django.contrib import messages, auth 
kemudian impor juga from django.contrib.auth.models import User 
pertama membuat obyek yang berisi dari input name di html nya, contoh firstname 
kemudian membuat validasi, jika password == confirm_password
dan jika User.objects yang memfilter cuma email ini aja, ternyata email yang di input sudah ada 
maka pakai messages.error(request, '') pesan error 
lalu redirect ke url register 
kalau tidak, object user yang bisa create_user berdasar first_name, last_name, email, username dan password 
yang tersimpan di obyek user.
maka autentikasi login memanggil user, dan reuest pesan yang akan di tampilkan 
yaitu sudah login, karena jika tidak akan muncul message.error
lalu di redirect ke dashboard dan user menyimpan.

Berlanjut jika pesan berhasil, maka tertulis Akunmu sudah terdaftar, lalu bawa ke halaman login 
dan jika tidak memenuhi syarat-syarat diatas, maka tertulis password gak sama 
jika tidak lagi, maka akan tertulis passowrd gak sama, tapi
jika masih gak cocok lagi,maka akan render dan nampil ke halaman register

Selanjutnya kita ke halaman loginnya di function login, kita bikin 

if request.method == 'POST':
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']

        user = auth.authenticate(username=username, password=password)
        if user is not None:
            auth.login(request, user)
            messages.success(request, 'login')
            return redirect('dashboard')
        else:
            messages.error(request, 'Gak bisa login')
            return redirect('login')

            
terus ke login.html di bagian form-group name email di ganti username
name="Password" di ganti jadi password, huruf kecil ya.. 
dan dibawah sign into your account kasih 
{% include 'includes/messages.html' %}


Sekarang kita bermain dengan session yaitu bagaimana setelah login juga harus ada logoutnya
kita mulai dengan topbar.html cari top-social-media dibawahnya kita kasih...
dari <ul> sampai </ul> nya ganti dengan script ini 

 

                <ul class="top-social-media pull-right">
                  {% if user.is_authenticated %}
                  <li>
                      <a href="{% url 'dashboard' %}" class="sign-in"><i class="fa fa-tachometer"></i> Dashboard</a>
                  </li>
                  <li>
                      <a href="javascript:{document.getElementById('logout').submit()}" class="sign-out"><i class="fa fa-sign-out"></i> Logout</a>
                      <form action="{% url 'logout' %}" id="logout" method="POST">
                      {% csrf_token %}
                      <input type="hidden">
                      </form>
                  </li>
                  {% else %}
                    <li>
                        <a href="{% url 'login' %}" class="sign-in"><i class="fa fa-sign-in"></i> Login</a>
                    </li>
                    <li>
                        <a href="{% url 'register' %}" class="sign-in"><i class="fa fa-user"></i> Register</a>
                    </li>
                    {% endif %}
                </ul>

 

ok jadi kita ada user yang sudah ada di views tadi ya
terus di jadikan conditional, jika user yang artinya adalah 
auth.authenticate(username=username, password=password)
dalam autentikasi yang di sini di tulis dengan 
{% if user.is_authenticated %}
munculkan url yang ada tulisan Dashboard nya dan pilihan logounya 
dimana tulisan dashboard itu isinya {% url 'dashboard' %} dan isi dari logout adalah 
javascript:{document.getElementById('logout').submit()} 
dan terdapat form action logout dengan method POST lalu di lindungi dengan {% csrf_token %}

Jika tidak dalam session atau tidak dalam authenticate
maka kasih pilihan tampilan login dan register.

Kemudian kita balik lagi ke views.py accounts disana kan sudah buat function logout 
persis dibawahnya def logout kita isi dengan 

if request.method == 'POST':
    auth.logout(request)
    return redirect('home')
return redirect('home')

Karena disitu keterangannya redirect ke 'home' jadi ada baiknya 
di home.html di <h3>Wow Factor Standard</h3> tambahkan juga 
{% include 'includes/home.html' %}
Kalau sudah, seharusnya tidak ada error dan berhasil work.

Sekarang kita gunakan dynamic title, yang artinya disetiap page manapun akan menyesuaikan nama titlenya
karena sejauh ini belum ada title di base.html bagian title kita kasih {% block title %} {% endtitle %}
begitupun di home.html dibawah {% extends 'base.html' %} kita kasih juga {% block title %} - Home {% endtitle %}
begitupun di halaman-halaman lain seperti about contact service login register dashboard juga ya
khusus untuk halaman produk detail misal car_detail.html ya, tinggal ambil {{single_car.car_title}} 
sehingga nama judul di H1 juga otomatis jadi di title page nya 

Sekarang kita kita coba lagi halaman login supaya user bisa login dengan menggunakan sosmednya 
menggunakan facebook atau google langsung
terus install 
pip install django-allauth, biasanya ada error nih, sehingga cryptography nya 
gak terinstall dengan sempurna, tinggal upgrade pip aja ya
kemudian di settings.py tambahkan 

'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.google',

Gampang kan? install allauth, terus tambahkan di INSTALLED_APPS settings.py 
nah, karena ini termasuk apps yang nantinya 
akan membutuhkan sebuah pengalamatan khusus
sehingga kita bikin url baru ya di urls.py direktori core project
path('socialaccounts/', include('allauth.urls')),
terus di settings.py paling bawah, tambahkan 
SITE_ID = 1

Terus lakukan python manage.py migrate 
Seharusnya tidak ada error dan akan berjalan dengan baik, maka tinggal jalankan 
dan langsung buka django admin, dan...

Dan dari sini kita bisa menambahkan API social accounts
misal pilih provider facebook, nah Client id bisa bikin dulu di developers.facebook.com
pilih get started atau my apps, pilih new apps atau create an app
pilih yang bisa untuk login atau everything else terus kasih nama appnya bakal apa
terus pilih create, atau biasanya di minta masukin password.

Terus pilih facebook login,pilih setup dan pilih www, terus masukin url https://localhost:8000/
terus pilih save. lalu klik Dashboard, dan pilih settings-> Basic, lalu ada app id, select dan copy
lalu paste di client id django admin tadi.

Terus yang di app secret fb tadi, copy dan paste ke django admin Add social application tadi 
Untuk key nya bisa di lewati, lalu ada pilihan Sites
yang example.com pindahin pakai tanda panah kanan lalu save

Terus balik ke index nya django admin ya, pilih yang sites, dan di sites itu
ganti jadi localhost:8000 terus save, kalau masih ada keliatan example.com 
select lalu remove aja, terus ke login.html diatas tambahkan 

{% load socialaccount %}
{% providers_media_js %}

Lalu di href nya facebook login ganti jadi {% provider_login_url 'facebook' method='js_sdk' %} 

Contact Form Send Messages

Di form contact, kita akan menjadikannya berfungsi, supaya user bisa mengirim pesan 
dan kita sebagai pemilik website bisa menerima pesannya, jadi kita bikin app baru 

python manage.py startapp contacts 

Seperti biasa, masukkan ke INSTALLED_APPS di settings.py terus bikin juga urls.py nya 
ini contoh yang saya buat, bisa di ikuti 
path('inquiry', views.inquiry, name='inquiry'),
lalu di direktori core projectnya 
path('contacts/', include('contacts.urls')),
terus bikin juga function di views nya
dari bikin juga models dulu ya, bisa contek pakai ini

class Contact(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    car_id = models.IntegerField()
    customer_need = models.CharField(max_length=100)
    car_title = models.CharField(max_length=100)
    city = models.CharField(max_length=100)
    state = models.CharField(max_length=100)
    email = models.EmailField(max_length=100)
    phone = models.CharField(max_length=100)
    message = models.TextField(max_length=100)
    user_id = models.IntegerField(blank=True)
    create_date = models.DateTimeField(blank=True, default=datetime.now)

    def __str__(self):
        return self.email

Setelah itu kita python manage.py makemigrations contacts jangan lupa di migrate juga ya
lalu, jangan lupa cek di database pgadmin ya...

Lanjut,,, kita register di admin.py nya, dan buat lagi class baru 

class ContactAdmin(admin.ModelAdmin):
    list_display = ('id', 'first_name', 'last_name', 'email', 'car_title', 'city', 'create_user')
    list_display_links = ('id', 'first_name', 'last_name')
    search_fields = ('first_name', 'last_name', 'email', 'car_title')
    list_per_page = 25

    
Jadi ngerti ya, admin.py ini isinya sebagai user interface antara sistem dan pengguna 
dengan role sebagai admin, untuk isi sourcenya ya di models.py itu tadi

Tadi kita udah buat models, lalu buat admin.py nya sekarang kita buat views.py nya, kita mulai dengan 
car_detail.html dulu, oh iya, setelah di perhatiin
saat klik send message di car_detail.html itu ternyata gak ada logonya
jadi di file htmlnya kita load static dulu ya...lalu di center juga gambarnya

terus cari form action, kita ubah jadi url ke inquiry dengan method POST
dibawahnya kasih script ini, diketik ya, jangan copas

 

{% csrf_token %}
{% if user.is_authenticated %}
<input type="hidden" name="user_id" value="{{user.id}}">
{% else %}
<input type="hidden" name="user_id" value="0">
{% endif %}
<input type="hidden" name="car_id" value="{{single_car.id}}">

 

lalu kita cocokkan ulang tag html lainnya seperti di form-group value nya kita ganti dengan 
{{ single_car.car_title }}

Kita ke car_detail.html cari heading-car dibawahnya kasih 

{% include 'includes/messages.html' %}

terus cari name="first_name" di sebelum required kasih script 

{% if user.is_authenticated %} value="{{user.first_name}}" {% endif %} 

begitupun di last_name, di sebelum required kasih juga 

{% if user.is_authenticated %} value="{{user.last_name}}" {% endif %} required

cari yang di name="email" juga, sama kasih aja script ini 

{% if user.is_authenticated %} value="{{user.email}}" {% endif %}

terus ke views.py kita impor 

from .models import Contact 
from django.core.mail import send_mail
from django.contrib.auth.models import User

supaya, apa yang di kirim oleh user yang otomatis masuk ke admin
juga terkirim ke email kita ya
selengkapnya baca dokumentasinya di https://docs.djangoproject.com/en/3.2/topics/email/
lalu kasih script ini 

def inquiry(request):
    if request.method == 'POST':
        car_id = request.POST['car_id']
        car_title = request.POST['car_title']
        user_id = request.POST['user_id']
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        customer_need = request.POST['customer_need']
        city = request.POST['city']
        state = request.POST['state']
        email = request.POST['email']
        phone = request.POST['phone']
        message = request.POST['message']

        #sebelum simpan database, memastikan dengan
        if request.user.is_authenticated:
            user_id = request.user.id
        #cek database apakah ada yang sama
            has_contacted = Contact.objects.all().filter(car_id=car_id, user_id=user_id)
            #ini akan mengembalikan pernyataan bahwa user yang sudah mengajukan penawaran
            #tidak akan mengirimkan pesan dan tidak akan masuk ke panel admin
            if has_contacted:
                messages.error(request, 'Udah minta penawaran gitu loh')
                return redirect('/cars/' +car_id)

        contact = Contact(car_id=car_id, car_title=car_title, user_id=user_id,
        first_name=first_name, last_name=last_name, customer_need=customer_need,
        city=city, state=state, email=email, phone=phone, message=message)

        #membuat obyek dari User yang telah di import 
        admin_info = User.objects.get(is_superuser=True)
        #obyek admin_email 
        admin_email = admin_info.email
        #diambil dari bawaan documentation django sending email
        send_mail(
                'Pesan Baru',
                'Ini Permintaan Baru dari ' + car_title + ' login ke panel admin',
                'email@webkita.com',
                [admin_email],
                fail_silently=False,
            )

        contact.save()
        messages.success(request, 'Terima kasih telah mengirim penawaran secepatnya akan kami balas')
        return redirect('/cars/'+car_id)

        
Sedangkan di settings.py di paling bawah, kasih ini ya

EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'gmail kamu'
EMAIL_HOST_PASSWORD = 'password gmail kamu'
EMAIL_USE_TLS = True

Sekalian ada commenting disana sebagai isi atau maksud dari codingan diatas ya
terdapat error saat mengirim pesan yang CC ke gmail kita, yang mana alasan keamanan
jadi saran saya, sebagai penerima gmail dari web ini, lebih baik gunakan 

https://myaccount.google.com/u/3/lesssecureapps?pli=1&rapt=AEjHL4PZAwi3h8UzCBBeHU5WFm8WqNqOb0UhbK3J9TyEmRtsmuflddZjny1F_8jXLy0dn1mhCeVzWNMr3jjohWsmhNaMeA_Szw 

Sayangnya terdapat risiko, yaitu enable less secure apps, alias mengizinkan 
tanpa keamanan, karena kalau di disable, email tidak akan terkirim, kita akan beda di lain waktu
Jika berhasil, seharusnya pesan yang dikirimkan user tidak hanya muncul di panel admin
tetapi juga terkirimkan ke gmail anda, pengirimnya adalah, alamat email dari pengguna 
yang pertama kali dipakai daftar di situs ini.

Apalagi ya.....eeeh kita utak-atik dashboardnya user, kalau diliat-liat saat user login
di dashboardnya terdapat tabel 5 kolom 3 row, sekarang akan kita ganti isi tersebut
mulai dari folder yang berisi apps accounts, buka lagi views.py di function dashboard
kita kasih query ini 

user_inquiry = Contact.objects.order_by('-create_date').filter(user_id=request.user.id)

Contact adalah class yang kita ambil dari models.py di contacts, pakai atribut objects.orderby()
di dalamnya pakai parameter '-create_date' dimana ini diambil dari properti di class Contact
lalu pakai function filter untuk memilih user.id dengan memakai request yang di simpan 
di user_id, seperti di atas-atas, jangan lupa menambahkan sebagai dictionary data.

Nah, setelah semua di simpan jadi 1 obyek, saatnya kita mencocokkan, data dari database 
yang akan di load di dashboard pengguna, kita buka templates/accounts/dashboard.html
di <span>user dan di class="active" ganti sama ini 
{{user.first_name}}

Nah, sekarang kita akan buat conditional, dimana kalau user login belum ada balasan inquiry
dari admin, maka akan ada tulisan, tidak ada inquiry, sebaliknya, jika ada, ya di tampilkan

jadi seluruh div class="main-title" itu select, dan ganti dengan ini 

 

    <div class="main-title" style="text-align:left !important;">
            <h1>Welcome <span>{{user.first_name}}</span></h1>
            <p>Here are the cars that you have inquired about</p>
        </div>
        {% if user_inquiry %}
        <table class="table table-hover">
          <thead>
          <tr>
            <th scope="col">#</th>
            <th scope="col">Car Name</th>
            <th scope="col">Location</th>
            <th scope="col">Price</th>
            <th scope="col">Action</th>
          </tr>
          </thead>
          <tbody>
          {% for inquiry in user_inquiry %}
          <tr>
            <th scope="row">1</th>
            <td>{{inquiry.car_title}}</td>
            <td>{{inquiry.city}}</td>
            <td><a href="{% url 'car_detail' inquiry.car_id %}" class="btn btn-outline-dark">View Car</a></td>
          </tr>
          {% endfor %}
          </tbody>
        </table>
        {% else %}
          <h4>You have no inquiries</h4>

        {% endif%}

    </div>

 

Saya jelaskan sedikit, jadi kita buat kondisional ya, dengan {% if user_inquiry %}
user_inquiry diambil dari function def dashboard di views.py nya accounts 
akan menampilkan isi table yang diberikan oleh admin, seluruh table yang tadinya 3 row 
sudah di pangkas jadi cuma 1 row saja,dengan perulangan akan muncul tergantung seberapa banyak 
data yang diambil dari database, dan jangan lupa pakai {% else %} lalu akhiri {% endif %}

untuk function dashboard sedikit ada yang berbeda, dengan cara impor 

from django.contrib.auth.decorators import login_required

@login_required(login_url = 'login')
def dashboard(request):
    user_inquiry = Contact.objects.order_by('-create_date').filter(user_id=request.user.id)
    data = {
        'user_inquiry': user_inquiry,
    }
    return render(request, 'accounts/dashboard.html', data)
    

Sebaris code yang diawali @login adalah decorator, saya harap sudah memahami apa itu decorator
jika belum bisa googling dulu ya, dan itu yang di import adalah library bawaan untuk decoratornya login 
jadi tinggal pakai @login_required aja, bukan seperti kalau kita buat decorator dulu dari awal
karena ini udah tersedia  dari django dan tinggal pakai.

Gunanya apa sih? jika user tidak login, tidak bisa melihat isi dashboard, tadinya kalau user belum login 
isi dashboard hanyalah You have no inquiries 
maka, jika dengan menggunakan decorator @login_required(login_url = 'login') user yang belum login 
tidak bisa melihat dashboard dan di alihkan ke halaman login, contohnya SS dibawah ini:

Dan berikut adalah kode lengkap dari views.py milik apps accounts 

from django.shortcuts import render, redirect
from django.contrib import messages, auth
from django.contrib.auth.models import User
from contacts.models import Contact
from django.contrib.auth.decorators import login_required

# Create your views here.
def login(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']

        user = auth.authenticate(username=username, password=password)

        if user is not None:
            auth.login(request, user)
            messages.success(request, 'berhasil login.')
            return redirect('dashboard')
        else:
            messages.error(request, 'Gak bisa login')
            return redirect('login')

    return render(request, 'accounts/login.html')

def register(request):
    if request.method == 'POST':
        firstname = request.POST['firstname']
        lastname = request.POST['lastname']
        username = request.POST['username']
        email = request.POST['email']
        password = request.POST['password']
        confirm_password = request.POST['confirm_password']
        if password == confirm_password:
            if User.objects.filter(username=username).exists():
                messages.error(request, 'Username sudah ada')
                return redirect('register')
            else:
                if User.objects.filter(email=email).exists():
                    messages.error(request, 'Email sudah ada ')
                    return redirect('register')
                else:
                    user = User.objects.create_user(first_name=firstname, last_name=lastname, email=email, username=username, password=password)
                    auth.login(request, user)
                    messages.success(request, 'sudah login')
                    return redirect('dashboard')
                    user.save()
                    messages.success(request, 'Akunmu sudah terdaftar')
                    return redirect('login')
        else:
            messages.error(request, 'Password gak sama')
    else:
        return render(request, 'accounts/register.html')

def logout(request):
    if request.method == 'POST':
        auth.logout(request)
        #messages.success(request, 'Sudah logout')
        return redirect('home')
    return redirect('home')

@login_required(login_url = 'login')
def dashboard(request):
    user_inquiry = Contact.objects.order_by('-create_date').filter(user_id=request.user.id)
    data = {
        'user_inquiry': user_inquiry,
    }
    return render(request, 'accounts/dashboard.html', data)

    

Contact Form 

Sedikit berbeda sama yang diatas, kalau diatas kan mengirim pesan melalui halaman car_detail
kalau ini melalui contact form, dari awal kita sudah paham ya, kalau yang bertanggung jawab 
dengan segala tampilan disini adalah pages apps, skenarionya sama, mengirim pesan yang masuk ke email admin 
langsung saja, kita buka file contact.html 
untuk form action kita ganti jadi {% url 'contact' %}
lalu tambahkan {% include 'includes/messages.html' %} dan {% csrf_token %} dibawahnya.

Terus ke views.py nya pages, di bawah function contact tambahkan 

    if request.method == 'POST':
        name = request.POST['name']
        email = request.POST['email']
        subject = request.POST['subject']
        phone = request.POST['phone']
        message = request.POST['message']

        admin_info = User.objects.get(is_superuser=True)
        admin_email = admin_info.email

        send_mail(
                email_subject,
                message_body,
                'bintangdirgantara03@gmail.com',
                [admin_email],
                fail_silently=False,
            )
        messages.success(request, 'Terima kasih telah menghubungi, segera akan balas pesan')
        return redirect('contact')

Seharusnya akan berjalan dengan baik, dan kita akan coba.

Berhasil!

Perintah dump database django postgresql

python manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4 > namafile.json


Kalau pakai atom, di sidebar akan muncul namafile.json itu adalah hasil ekstrak database yang berupa json
yang nantinya akan digunakan untuk keperluan deploy ke server, dalam kasus ini heroku.
Seperti biasa, daftar dan buat account, kali ini di heroku, install dulu ya
download heroku di web resminya

Setelah itu, cek dulu .gitignore hapus dulu yang media 
terus di root folder / core project, bikin file Procfile
isikan 

release: python manage.py migrate
web: gunicorn car.wsgi

Di root folder atau core project, buka file wsgi.py liat di os.environ.setdefault
yang paling belakang itu ada namaproject.settings, nah ambil aja nama projectnya apa
jadi di Procfile isinya gunicorn car.wsgi kalau di saya.

terus bikin file runtime.txt yang isinya versi python yang dipakai 
cara ngeceknya tinggal masuk mode interaktif python aja 
dan ngetiknya pake python huruf kecil ya p nya, bukan P huruf besar
terus bikin requirements.txt dengan cara pip freeze > requirements.txt 

Terus dari git console ketik heroku login, terus ketik sembarang 
biar otomatis buka browser, terus klik login seperti biasa
kalau sudah login, bisa dibiarkan lalu buka gitbash baru, atau ctrl+c 
lalu ketik N untuk tetap login dan ketik untuk memastikan heroku whoami 
kalau masih ada keterangan email yang terdaftar, berarti masih di session tersebut.

Kita install gunicorn dan psycopg, FYI aja psycopg2 adalah package
untuk mengaktifkan database support terhadap postgresql sedangkan gunicorn
adalah green unicorn sebuah http server untuk python berbasis WSGI atau web server gateway interface
kita install dengan cara 

pip install gunicorn psycopg2-binary lalu kita pip freeze > requirements.txt lagi 
dan git init juga git add -A lagi yang artinya menambahkan semua file 
terus commit juga ya, lalu ketikkan heroku create

Terus kita install pip install dj-database-url, terus impor di settings.py 
import dj_database_url
setelah itu, di settingan database yang json itu, di commenting semua 
lalu ganti dengan 

DATABASE = {
    'default': dj_database_url.config(default='postgres://user:pass@localhost/dbname')
}

itu yang user tinggal di ganti nama database ya, begitupun dengan passnya, password kamu 
dbname ganti juga nama databasenya, ohiya jangan lupa di pip freeze > requirements.txt lagi ya 
setelah menambahkan sesuatu yang baru, dan satu lagi hal yang harus di ingat adalah.

Kapanpun kita pakai apps di production server, DEBUG harus di ganti dengan False
maksudnya adalah, selama masih devel di lokal mesti pakai True
sekarang kita install lagi package khusus untuk penggunaan heroku ke host 
buat static files kita, pip install whitenoise 
setelah itu taruh command ini di settings.py bagian paling bawah 

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticStorage'
terus di middleware nya kita tambahkan lagi 
whitenose.middleware.WhiteNoiseMiddleware
setelah itu kita gith push atas perubahan yang barusan di lakukan
biasakan cek dengan perintah git status 
kalau di saya hasilnya muncul 
....
 modified:   car/settings.py
....
terus git add -A lagi terus git commit "keterangan" lagi, nah, baru setelah itu
git push heroku master  
Kali ini agak lama uploadnya, ya tergantung koneksi masing-masing sih, jajajajaja
Setelah itu ketik heroku open
Kalau terjadi Bad Request 400, biasanya karena terlalu banyak url di apps kita 
langsung aja buka django application settings.py di ALLOWED_HOSTS di dalam bracket itu 
kasih 'linkkamu.herokuapp.com', 'domainkamu.com', 'www.domainkamu.com' 
dua pilihan terakhir jika kamu nanti ada domain tersendiri ya, maksudnya bukan pakai herokuapp saja 

Terus ketik heroku open git add -A lagi terus git commit -m 'keterangan' lagi 
terus ketik 'git push heroku master' lagi (gak pake kutip ya) setelah itu 
ketik aja heroku open dan website kamu akan release di herokuapp.

Biasanya kalau ada gambar yang nggak ke load coba 
DEBUG nya settings.py ganti jadi True 
heroku run python manage.py loaddata namadatabase.json 
json ini yang di ekstrak tadi ya 
python manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
terus di .gitignore paling bawah kasih /media setelah itu cek lagi 
git status gunanya untuk lihat ada perubahan apa aja yang baru kamu update 
terus git commit -m "keterangannya"
setelah itu git push heroku master lagi.

Jadi gitu ya konsepnya, kalau di local ada perbaikan, cek lagi pakai git status 
kalau sudah yakin git commit -m, kalau udah git push heroku master 
gunanya upload ke live production nya heroku.
Setelah di reload page, harusnya berhasil.

Bikin Custom Domain 

Ini kan masih pake subdomainapp.herokuapp.com ya, sekarang kita setup dengan domain custom 
klik dashboard nya heroku, terus pilih tab settings, scroll paling bawah 
disitu ada add domain, klik aja terus tulis alaman domain kamu, caranya
*.namadomain.com terus klik Next, nah di situ ada semacam key di kolom DNS Target.

Terus klik lagi bikin add domain kali ini yang lengkap pakai www 
pilih DNS Target yang barisnya *.domainkamu.com di copy aja 
terus paste ke Domain Manager, contohnya di sini saya pakai godaddy.com 
terus klik domain kamu tepatnya di Manage DNS, cari aja pelan-pelan,
nah di situ ada Records nya, nah key yang kamu udah copy tadi di DNS Target
pastekan di kolom Points to   (contohnya gambar di bawah)

Kalau udah kurang lebih begini lah, tinggal tunggu propagation kelar aja sih...

Beberapa kasus terdapat Error DoesNotExist saat hendak login user dengan pesan error 
karena Site maching query not exist solusinya, kita cek di settings.py 
di bagian SITE_ID = kan tadi masih nilai nya 1 ya, sebenarnya apa sih itu ?
sederhananya ini adalah default site yang di pake di development mode 
jadinya kita mesti migrate dari local ke prodcution, jadinya kita harus nambah 
add nama domain di database, biasanya ada 2 pilihan dari admin panel 
itu kalo admin panel gak error, kalo error, kalo error ya jadinya dari database 
melalui codingan, kita mulai dengan python interactive 

heroku run python manage.py shell
lalu kita impor 
from django.contrib.sites.models import Site 
site = Site()
site.domain = 'domainkamu.com' 
site.name = 'domainkamu.com' 
site.save()
print(Site.objects.get(name='domainkamu.com').id) [enter]
akan muncul berapa itu angkanya ? nah itu baru ganti ke SITE_ID = di settings.py tadi 
setelah itu git add -A lagi git commit lagi terus git push heroku master lagi
terus coba ke admin page dan login atau register page.

Pastikan juga hal lainnya, seperti api login facebook atau googlenya
masukkan namadomain.com di Sites bagian socialapp nya, termasuk yang di developersnya
seperti developers.facebook.com dan google developer panel nya, untuk mengganti 
yang tadinya localhost:8000 jadi http://subdomain.herokuapp.com bukan yang domainkamu.com ya
kenapa ? sederhana, karena yang terdaftar di host kamu aslinya kan yang https://subdomain.herokuapp.com

Armin

Armin

IT Dev, SEO & Digital Marketing Specialist with 7+ years experience, Coder, Sys Admin, Designer, Blogger