Commit d620aa9a authored by impfundev's avatar impfundev

first commit

parents
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class AuthenticationsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'authentications'
from django import forms
class LoginForm(forms.Form):
# template_name = "form_snippet.html"
email = forms.EmailField(
widget=forms.TextInput(
attrs={
"placeholder": "Email",
"class": "form-control",
}
)
)
password = forms.CharField(
widget=forms.PasswordInput(
attrs={
"placeholder": "Password",
"class": "form-control",
}
)
)
class SignUpForm(forms.Form):
name = forms.CharField(
max_length=50,
widget=forms.TextInput(
attrs={
"placeholder": "Name",
"class": "form-control",
}
),
)
email = forms.EmailField(
widget=forms.TextInput(
attrs={
"placeholder": "Email",
"class": "form-control",
}
)
)
password = forms.CharField(
max_length=255,
widget=forms.TextInput(
attrs={
"placeholder": "Password",
"class": "form-control",
}
),
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Django Library</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
/>
</head>
<body>
{% block content %}{% endblock content %}
<script
src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
crossorigin="anonymous"
></script>
</body>
</html>
{% extends "base.html" %} {% block content %}
<main
style="min-height: 100vh"
class="w-100 h-100 bg-body-secondary d-flex justify-content-center align-items-center"
>
<form
action="/auth/login/"
method="POST"
class="card w-25 p-4 rounded-4 shadow"
>
<h1 class="h3 text-center mb-4">Login</h1>
{% csrf_token %} {% for field in form %}
<div class="form-outline form-white mb-3">{{ field }}</div>
{% endfor %}
<button
type="submit"
id="submit-login"
class="btn btn-primary my-2 rounded-5"
>
Login
</button>
{% if error_message %}
<p class="alert alert-warning small" role="alert">
<i class="bi bi-exclamation-circle"></i> {{ error_message }}
</p>
{% endif %}
<p class="my-2">
Don't have an account? <a href="/auth/sign-up">Sign Up</a>
</p>
</form>
</main>
{% endblock content %}
{% extends "base.html" %} {% block content %}
<main
style="min-height: 100vh"
class="w-100 h-100 bg-body-secondary d-flex justify-content-center align-items-center"
>
<form
action="/auth/sign-up/"
method="POST"
class="card w-25 p-4 rounded-4 shadow"
>
<h1 class="h3 text-center mb-4">Sign Up</h1>
{% csrf_token %} {% for field in form %}
<div class="form-outline form-white mb-3">{{ field }}</div>
{% endfor %}
<button
type="submit"
id="submit-sign-up"
class="btn btn-primary my-2 rounded-5"
>
Login
</button>
{% if error_message %}
<p class="alert alert-warning small" role="alert">
<i class="bi bi-exclamation-circle"></i> {{ error_message }}
</p>
{% endif %}
<p class="my-2">Already have an account? <a href="/auth/login">Login</a></p>
</form>
</main>
{% endblock content %}
from django.test import TestCase
# Create your tests here.
from django.urls import path
from authentications.views import login, sign_up
urlpatterns = [
path("login/", login, name="login"),
path("sign-up/", sign_up, name="sign_up"),
]
import jwt
from django.http import HttpResponseRedirect
from django.shortcuts import render
from authentications.forms import LoginForm, SignUpForm
from librarians.models import Librarians, LoginHistory
def login(request):
librarian = Librarians.objects.all()
context = {"form": LoginForm()}
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
account = librarian.filter(
email=form.data["email"], password=form.data["password"]
)
if account.exists():
librarian = librarian.get(
email=form.data["email"],
password=form.data["password"],
)
payload = {
"librarian_id": librarian.id,
"name": librarian.name,
"email": librarian.email,
}
token = jwt.encode(payload, "secret", algorithm="HS256")
request.session["auth_session"] = token
LoginHistory.objects.create(librarian_id=librarian.id)
return HttpResponseRedirect("/dashboard/")
else:
context["error_message"] = (
"Email or Password invalid, please enter valid data or Sign Up first"
)
else:
form = LoginForm()
return render(request, "login.html", context)
def sign_up(request):
librarian = Librarians.objects.all()
context = {"form": SignUpForm()}
if request.method == "POST":
form = SignUpForm(request.POST)
if form.is_valid():
is_email = librarian.filter(email=form.data["email"])
if is_email.exists():
context["error_message"] = (
"Email was already exist, please use different email"
)
else:
librarian.create(
name=form.data["name"],
email=form.data["email"],
password=form.data["password"],
)
librarian_id = librarian.get(
name=form.data["name"],
email=form.data["email"],
password=form.data["password"],
).id
LoginHistory.objects.create(librarian_id=librarian_id)
return HttpResponseRedirect("/dashboard/")
else:
form = SignUpForm()
return render(request, "sign_up.html", context)
from django.contrib import admin
from book_loans.models import BookLoans
admin.site.register(BookLoans)
from django.apps import AppConfig
class BookLoansConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'book_loans'
# Generated by Django 4.2 on 2024-06-26 07:38
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('members', '0001_initial'),
('books', '0001_initial'),
('librarians', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='BookLoans',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('notes', models.TextField(blank=True, null=True)),
('loan_date', models.DateTimeField()),
('due_date', models.DateTimeField()),
('return_date', models.DateTimeField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('book', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='books.book')),
('issued_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='librarians.librarians')),
('member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.members')),
],
options={
'db_table': 'book_loans',
},
),
]
# Generated by Django 4.2 on 2024-06-26 07:41
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('members', '0001_initial'),
('books', '0001_initial'),
('book_loans', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='bookloans',
name='book',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='books.book'),
),
migrations.AlterField(
model_name='bookloans',
name='member',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='members.members'),
),
]
# Generated by Django 4.2 on 2024-06-26 07:42
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('book_loans', '0002_alter_bookloans_book_alter_bookloans_member'),
]
operations = [
migrations.RenameField(
model_name='bookloans',
old_name='issued_by',
new_name='librarians',
),
]
from django.db import models
from books.models import Book
from members.models import Members
from librarians.models import Librarians
class BookLoans(models.Model):
book = models.ForeignKey(to=Book, on_delete=models.SET_NULL, null=True)
member = models.ForeignKey(to=Members, on_delete=models.SET_NULL, null=True)
librarians = models.ForeignKey(to=Librarians, on_delete=models.SET_NULL, null=True)
notes = models.TextField(blank=True, null=True)
loan_date = models.DateTimeField()
due_date = models.DateTimeField()
return_date = models.DateTimeField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "book_loans"
from django.test import TestCase
# Create your tests here.
from django.shortcuts import render
# Create your views here.
from django.contrib import admin
from books.models import Book
admin.site.register(Book)
from django.apps import AppConfig
class BooksConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'books'
from django import forms
class BookForm(forms.Form):
title = forms.CharField(
max_length=100,
widget=forms.TextInput(
attrs={
"placeholder": "Title",
"class": "form-control",
}
),
)
description = forms.CharField(
max_length=255,
widget=forms.Textarea(
attrs={
"placeholder": "Description",
"class": "form-control",
}
),
)
# Generated by Django 4.2 on 2024-06-26 07:28
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Book',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('description', models.CharField(max_length=255)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'db_table': 'book',
},
),
]
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
description = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "book"
<form
class="modal fade"
id="book_modal_create"
tabindex="-1"
aria-labelledby="book_modal_label"
aria-hidden="true"
action="/dashboard/books/"
method="POST"
>
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Input Data</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
{% csrf_token %} {% for field in form %}
<div class="form-outline form-white mb-3">{{ field }}</div>
{% endfor %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</form>
{% for book in books %}
<form
class="modal fade"
id="book_delete_modal_{{ book.id }}"
tabindex="-1"
aria-labelledby="book_delete_label"
aria-hidden="true"
action="/dashboard/books/{{ book.id }}/delete/"
method="POST"
>
{% csrf_token %}
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">
Are you sure want to delete <b>{{ book.title }}</b>?
</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
Once data is deleted, it cannot be restored.
<input type="hidden" name="id" id="almacen_id" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Cancel
</button>
<button type="submit" class="btn btn-danger">Continue</button>
</div>
</div>
</div>
</form>
{% endfor %}
{% extends "layout.html" %} {% block dashboard %}
<div style="max-width: 80vw" class="w-100 p-4">
<div class="d-flex flex-column gap-2 mb-4">
<button
type="button"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#book_modal_create"
>
<i class="bi bi-plus-circle"></i> Add Book
</button>
{% include "create_form.html" %}
</div>
{% include "table_data.html" %} {% include "delete_form.html" %}
</div>
{% endblock dashboard %}
<table class="table table-hover">
<thead>
<tr class="table-primary">
<th scope="col">
<button class="btn">
<i class="bi bi-arrow-down-up"></i>
</button>
Title
</th>
<th scope="col">
<button class="btn">
<i class="bi bi-arrow-down-up"></i>
</button>
Description
</th>
<th scope="col">
<button class="btn">
<i class="bi bi-arrow-down-up"></i>
</button>
Created At
</th>
<th scope="col">
<button class="btn">
<i class="bi bi-arrow-down-up"></i>
</button>
Updated At
</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% if books %} {% for book in books %}
<tr>
<td>{{ book.title }}</td>
<td>{{ book.description }}</td>
<td>{{ book.created_at }}</td>
<td>{{ book.updated_at }}</td>
<td class="d-flex gap-2">
<a
class="btn btn-success"
href="/dashboard/books/{{ book.id }}/update/"
>
<i class="bi bi-pencil-square"></i>
</a>
<button
class="btn btn-danger"
data-bs-toggle="modal"
data-bs-target="#book_delete_modal_{{ book.id }}"
>
<i class="bi bi-trash3-fill"></i>
</button>
</td>
</tr>
{% endfor %} {% else %}
<tr class="w-100">
<td></td>
<td></td>
<td>
<p>Data Empty</p>
</td>
<td></td>
<td></td>
</tr>
{% endif %}
</tbody>
</table>
{% extends "layout.html" %} {% block dashboard %}
<div style="max-width: 80vw" class="w-100 p-4">
<div class="d-flex flex-column gap-2 mb-4">
<form
id="book_update_modal_{{ book_id }}"
action="/dashboard/books/{{ book_id }}/update/"
method="POST"
>
{% csrf_token %}
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">Input Data</h1>
</div>
<div class="modal-body">
{% for field in form %}
<div class="form-outline form-white mb-3">{{ field }}</div>
{% endfor %}
<div class="d-flex gap-2">
<a href="/dashboard/books/" class="btn btn-secondary"> Cancel </a>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
{% endblock dashboard %}
from django.test import TestCase
# Create your tests here.
from django.urls import path
from books.views import index, update, delete
urlpatterns = [
path("", index, name="book_lists"),
path("<id>/update/", update, name="update_book"),
path("<id>/delete/", delete, name="delete_book"),
]
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from datetime import datetime
from books.models import Book
from books.forms import BookForm
def index(request):
latest_book_list = Book.objects.order_by("created_at")[:10]
context = {"books": latest_book_list, "form": BookForm()}
if request.method == "POST":
form = BookForm(request.POST)
if form.is_valid:
title = form.data["title"]
description = form.data["description"]
Book.objects.create(title=title, description=description)
return render(request, "index.html", context)
def update(request, id):
latest_book_list = Book.objects.order_by("created_at")[:10]
context = {"books": latest_book_list}
book = Book.objects.get(id=id)
initial_dict = {"title": book.title, "description": book.description}
print(book.title)
form = BookForm(request.POST or None, initial=initial_dict)
if request.method == "POST":
if form.is_valid:
title = form.data["title"]
description = form.data["description"]
book = Book.objects.filter(id=id)
book.update(title=title, description=description, updated_at=datetime.now())
return HttpResponseRedirect("/dashboard/books")
context["form"] = form
context["book_id"] = id
return render(request, "update_form.html", context)
def delete(request, id):
context = {}
book = get_object_or_404(Book, id=id)
if request.method == "POST":
book.delete()
return HttpResponseRedirect("/dashboard/books")
return render(request, "index.html", context)
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class DashboardsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'dashboards'
from django.db import models
{% extends "layout.html" %} {% block dashboard %}
<div style="max-width: 80vw" class="w-100 p-4">
<div class="row container">
<div class="col">
<div class="card h-100 d-flex flex-column">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-book-half"></i> Book</h5>
<p class="card-text">
Explore the many amazing books available in this library!
</p>
</div>
<div class="card-footer">
<a href="#" class="btn btn-primary">Explore Book</a>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title"><i class="bi bi-person-vcard"></i> Member</h5>
<p class="card-text">
Manage your membership or become a member of the library to start
borrowing your first book
</p>
</div>
<div class="card-footer">
<a href="#" class="btn btn-primary">Go to Member</a>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">
<i class="bi bi-person-fill-check"></i> Librarian Access
</h5>
<p class="card-text">Manage and Controll Book, Member, Access, etc</p>
</div>
<div class="card-footer">
<a href="#" class="btn btn-primary">Go to Librarian Access</a>
</div>
</div>
</div>
</div>
</div>
{% endblock dashboard %}
{% extends "base.html" %} {% block content %}
<main
style="min-height: 100vh"
class="w-100 h-100 bg-body-secondary d-flex flex-column justify-content-center align-items-center"
>
<h2 class="h3">Welcome to</h2>
<h1 class="h1">Django Library Management System</h1>
<section
class="d-flex flex-column justify-content-center align-items-center my-3 w-100"
>
<h4 class="h4">Let's get started</h4>
<div class="d-flex gap-2 my-2">
<a href="/auth/login" class="btn btn-outline-primary">Login</a>
<a href="/auth/sign-up" class="btn btn-primary">Sign Up</a>
</div>
</section>
</main>
{% endblock content %}
{% extends "base.html" %} {% block content %}
<main
style="min-height: 100vh"
class="w-100 h-100 bg-body-secondary d-flex justify-content-end"
>
<div
class="w-100 p-4 d-flex flex-column gap-4 bg-body"
style="max-width: 20vw"
>
<h5 class="h4">{{ user_session.name }}</h5>
<div class="d-flex flex-column gap-2">
<a href="/dashboard" class="btn btn-outline-primary text-start w-100"
><i class="bi bi-house-fill"></i> Home</a
>
<a
href="/dashboard/books"
class="btn btn-outline-primary text-start w-100"
><i class="bi bi-book-half"></i> Books</a
>
<a
href="/dashboard/members"
class="btn btn-outline-primary text-start w-100"
><i class="bi bi-person-vcard"></i> Members</a
>
<a
href="/dashboard/librarians"
class="btn btn-outline-primary text-start w-100"
><i class="bi bi-person-fill-lock"></i> Librarian Access</a
>
</div>
</div>
{% block dashboard %}{% endblock dashboard %}
</main>
{% endblock content %}
from django.test import TestCase
# Create your tests here.
from django.urls import path, include
from dashboards.views import home, index
urlpatterns = [
path("", index, name="dashboard"),
path("books/", include("books.urls")),
path("members/", include("members.urls")),
]
import jwt
from django.shortcuts import render
def home(request):
return render(request, "homepage.html")
def index(request):
auth_session = request.session["auth_session"]
decoded = jwt.decode(auth_session, "secret", algorithms=["HS256"])
print(decoded)
context = {"user_session": decoded}
return render(request, "dashboard/index.html", context)
File added
from django.contrib import admin
from librarians.models import Librarians
admin.site.register(Librarians)
from django.apps import AppConfig
class LibrariansConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'librarians'
# Generated by Django 4.2 on 2024-06-26 07:38
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Librarians',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('email', models.EmailField(max_length=254)),
('password', models.CharField(max_length=255)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'db_table': 'librarians',
},
),
]
# Generated by Django 4.2 on 2024-06-26 08:35
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('librarians', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='LoginHistory',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('login_at', models.DateTimeField(auto_now_add=True)),
('librarian', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='librarians.librarians')),
],
),
]
# Generated by Django 4.2 on 2024-06-26 08:37
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('librarians', '0002_loginhistory'),
]
operations = [
migrations.AlterModelTable(
name='loginhistory',
table='librarians_login_histories',
),
]
from django.db import models
class Librarians(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
password = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "librarians"
class LoginHistory(models.Model):
librarian = models.ForeignKey(to=Librarians, on_delete=models.CASCADE)
login_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = "librarians_login_histories"
from django.test import TestCase
# Create your tests here.
from django.shortcuts import render
# Create your views here.
"""
ASGI config for library_django project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'library_django.settings')
application = get_asgi_application()
"""
Django settings for library_django project.
Generated by 'django-admin startproject' using Django 5.0.6.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-3-$!7+86e)2ps3i+3=da5(7-a=gt$p_@+=)fuh2jj-2!eym$3y"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"books.apps.BooksConfig",
"book_loans.apps.BookLoansConfig",
"members.apps.MembersConfig",
"librarians.apps.LibrariansConfig",
"authentications.apps.AuthenticationsConfig",
"dashboards.apps.DashboardsConfig",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "library_django.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "library_django.wsgi.application"
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "Asia/Jakarta"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
STATIC_URL = "static/"
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
"""
URL configuration for library_django project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
urlpatterns = [
path("dashboard/", include("dashboards.urls")),
path("admin/", admin.site.urls),
path("auth/", include("authentications.urls")),
]
"""
WSGI config for library_django project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'library_django.settings')
application = get_wsgi_application()
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'library_django.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
from django.contrib import admin
from members.models import Members
admin.site.register(Members)
from django.apps import AppConfig
class MembersConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'members'
from django import forms
class MemberForm(forms.Form):
name = forms.CharField(
max_length=50,
widget=forms.TextInput(
attrs={
"placeholder": "Name",
"class": "form-control",
}
),
)
email = forms.CharField(
max_length=255,
widget=forms.EmailInput(
attrs={
"placeholder": "Email",
"class": "form-control",
}
),
)
password = forms.CharField(
max_length=255,
widget=forms.TextInput(
attrs={
"placeholder": "Password",
"class": "form-control",
}
),
)
# Generated by Django 4.2 on 2024-06-26 07:38
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Members',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('email', models.EmailField(max_length=254)),
('password', models.CharField(max_length=255)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'db_table': 'members',
},
),
]
from django.db import models
class Members(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
password = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "members"
{% extends "layout.html" %} {% block dashboard %}
<div style="max-width: 80vw" class="w-100 p-4">
{% include "members_delete_form.html" %}
<div class="d-flex flex-column gap-2 mb-4">
<button
type="button"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#member_modal_create"
>
<i class="bi bi-plus-circle"></i> Add Member
</button>
{% include "members_create_form.html" %}
</div>
{% include "members_table_data.html" %}
</div>
{% endblock dashboard %}
<form
class="modal fade"
id="member_modal_create"
tabindex="-1"
aria-labelledby="member_modal_label"
aria-hidden="true"
action="/dashboard/members/"
method="POST"
>
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Input Data</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
{% csrf_token %} {% for field in form %}
<div class="form-outline form-white mb-3">{{ field }}</div>
{% endfor %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</form>
{% for member in members %}
<form
class="modal fade"
id="member_delete_modal_{{ member.id }}"
tabindex="-1"
aria-labelledby="member_delete_label"
aria-hidden="true"
action="/dashboard/members/{{ member.id }}/delete/"
method="POST"
>
{% csrf_token %}
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">
Are you sure want to delete <b>{{ member.title }}</b>?
</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
Once data is deleted, it cannot be restored.
<input type="hidden" name="id" id="almacen_id" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Cancel
</button>
<button type="submit" class="btn btn-danger">Continue</button>
</div>
</div>
</div>
</form>
{% endfor %}
<table class="table table-hover">
<thead>
<tr class="table-primary">
<th scope="col">
<button class="btn">
<i class="bi bi-arrow-down-up"></i>
</button>
Name
</th>
<th scope="col">
<button class="btn">
<i class="bi bi-arrow-down-up"></i>
</button>
Email
</th>
<th scope="col">
<button class="btn">
<i class="bi bi-arrow-down-up"></i>
</button>
Created At
</th>
<th scope="col">
<button class="btn">
<i class="bi bi-arrow-down-up"></i>
</button>
Updated At
</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% if members %} {% for member in members %}
<tr>
<td>{{ member.name }}</td>
<td>{{ member.email }}</td>
<td>{{ member.created_at }}</td>
<td>{{ member.updated_at }}</td>
<td class="d-flex gap-2">
<a
class="btn btn-success"
href="/dashboard/members/{{ member.id }}/update/"
>
<i class="bi bi-pencil-square"></i>
</a>
<button
class="btn btn-danger"
data-bs-toggle="modal"
data-bs-target="#member_delete_modal_{{ member.id }}"
>
<i class="bi bi-trash3-fill"></i>
</button>
</td>
</tr>
{% endfor %} {% else %}
<tr class="w-100">
<td></td>
<td></td>
<td>
<p>Data Empty</p>
</td>
<td></td>
<td></td>
</tr>
{% endif %}
</tbody>
</table>
{% extends "layout.html" %} {% block dashboard %}
<div style="max-width: 80vw" class="w-100 p-4">
<div class="d-flex flex-column gap-2 mb-4">
<h1 class="h3">Update Data</h1>
<form
id="member_update_modal_{{ member_id }}"
action="/dashboard/members/{{ member_id }}/update/"
method="POST"
>
{% csrf_token %}
<div class="d-flex flex-column gap-1">{{ form }}</div>
<div class="d-flex gap-2 my-3">
<a href="/dashboard/members/" class="btn btn-secondary">Cancel</a>
<button class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
{% endblock dashboard %}
from django.test import TestCase
# Create your tests here.
from django.urls import path
from members.views import index, update, delete
urlpatterns = [
path("", index, name="member_lists"),
path("<id>/update/", update, name="update_member"),
path("<id>/delete/", delete, name="delete_member"),
]
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from datetime import datetime
from members.models import Members
from members.forms import MemberForm
def index(request):
latest_memeber_list = Members.objects.order_by("created_at")[:10]
context = {"members": latest_memeber_list, "form": MemberForm()}
if request.method == "POST":
form = MemberForm(request.POST)
if form.is_valid:
name = form.data["name"]
email = form.data["email"]
password = form.data["password"]
Members.objects.create(name=name, email=email, password=password)
return render(request, "members.html", context)
def update(request, id):
latest_member_list = Members.objects.order_by("created_at")[:10]
context = {"members": latest_member_list}
member = Members.objects.get(id=id)
initial = {
"name": member.name,
"email": member.email,
"password": member.password,
}
form = MemberForm(request.POST or None, initial=initial)
if request.method == "POST":
if form.is_valid:
name = form.data["name"]
email = form.data["email"]
password = form.data["password"]
member = Members.objects.filter(id=id)
member.update(
name=name, email=email, password=password, updated_at=datetime.now()
)
return HttpResponseRedirect("/dashboard/members")
context["form"] = form
context["member_id"] = id
return render(request, "members_update_form.html", context)
def delete(request, id):
context = {}
member = get_object_or_404(Members, id=id)
if request.method == "POST":
member.delete()
return HttpResponseRedirect("/dashboard/members")
return render(request, "members.html", context)
asgiref==3.8.1
Django==4.2
sqlparse==0.5.0
tzdata==2024.1
\ No newline at end of file
from django.apps import AppConfig
class TestsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'tests'
from django.test import TestCase
from books.models import Book
class BookModelTestCase(TestCase):
def setUp(self):
self.title = "Test Book"
self.description = "It's just Book created for testing!"
Book.objects.create(title=self.title, description=self.description)
def test_get_books(self):
"""Should get all books"""
books = Book.objects.all()
self.assertIsNotNone(books)
def test_get_book_by_field(self):
"""Should get book by field"""
book = Book.objects.get(title=self.title)
self.assertEqual(book.title, self.title)
def test_create_new_book(self):
"""Should create new book"""
title = "New book"
description = "This is new book, created just for testing!"
Book.objects.create(title=title, description=description)
new_book = Book.objects.get(title=title)
self.assertEqual(new_book.title, title)
self.assertEqual(new_book.description, description)
def test_update_book(self):
"""Should update book fields"""
new_title = "This is updated title!"
Book.objects.filter(title=self.title).update(title=new_title)
updated_book = Book.objects.get(title=new_title)
self.assertEqual(updated_book.title, new_title)
def test_delete_book(self):
book = Book.objects.get(title=self.title)
book.delete()
self.assertRaises(Book.DoesNotExist, Book.objects.get, title=book.title)
{
"routes": [
{
"src": "/(.*)",
"dest": "library_django/wsgi.py"
}
]
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment