Commit 0bde8217 authored by impfundev's avatar impfundev

feat: book cover image

parent cb47d04a
......@@ -5,6 +5,7 @@
**/__pycache__/**
*.sqlite3
media
uploads
# Backup files #
*.bak
......
......@@ -5,9 +5,15 @@ from books.models import Book
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ["title", "stock", "category", "description"]
fields = ["cover_image", "title", "stock", "category", "description"]
widgets = {
"cover_image": forms.FileInput(
attrs={
"placeholder": "Cover Image",
"class": "form-control",
}
),
"title": forms.TextInput(
attrs={
"placeholder": "Title",
......
# Generated by Django 5.0.6 on 2024-07-10 04:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('books', '0003_book_category'),
]
operations = [
migrations.AddField(
model_name='book',
name='cover_image',
field=models.ImageField(blank=True, null=True, upload_to='uploads'),
),
]
# Generated by Django 5.0.6 on 2024-07-10 05:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('books', '0004_book_cover_image'),
]
operations = [
migrations.AlterField(
model_name='book',
name='cover_image',
field=models.ImageField(blank=True, null=True, upload_to=''),
),
]
# Generated by Django 5.0.6 on 2024-07-10 05:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('books', '0005_alter_book_cover_image'),
]
operations = [
migrations.AlterField(
model_name='book',
name='cover_image',
field=models.ImageField(blank=True, null=True, upload_to='uploads'),
),
]
# Generated by Django 5.0.6 on 2024-07-10 05:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('books', '0006_alter_book_cover_image'),
]
operations = [
migrations.AlterField(
model_name='book',
name='cover_image',
field=models.ImageField(blank=True, null=True, upload_to='media/uploads'),
),
]
# Generated by Django 5.0.6 on 2024-07-10 05:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('books', '0007_alter_book_cover_image'),
]
operations = [
migrations.AlterField(
model_name='book',
name='cover_image',
field=models.ImageField(blank=True, null=True, upload_to='uploads'),
),
]
......@@ -9,6 +9,7 @@ class Book(models.Model):
category = models.ForeignKey(
to=Category, on_delete=models.CASCADE, blank=True, null=True
)
cover_image = models.ImageField(upload_to="uploads", blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
......
<table class="table table-hover">
<thead>
<tr class="table-primary">
<th scope="col">Cover</th>
<th scope="col">Title</th>
<th scope="col">Category</th>
<th scope="col">Stock</th>
......@@ -13,19 +14,34 @@
<tbody>
{% if object_list %} {% for book in object_list %}
<tr>
<td>
{% if book.cover_image %}
<img
style="object-fit: contain"
width="100"
height="100"
src="{{ book.cover_image.url }}"
/>
{% endif %}
</td>
<td>{{ book.title }}</td>
<td>{{ book.category.name }}</td>
<td>{{ book.stock }}</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 }}/">
<i class="bi bi-pencil-square"></i>
</a>
<a class="btn btn-danger" href="/dashboard/books/{{ book.id }}/delete/">
<i class="bi bi-trash3-fill"></i>
</a>
<td>
<div class="d-flex gap-2">
<a class="btn btn-success" href="/dashboard/books/{{ book.id }}/">
<i class="bi bi-pencil-square"></i>
</a>
<a
class="btn btn-danger"
href="/dashboard/books/{{ book.id }}/delete/"
>
<i class="bi bi-trash3-fill"></i>
</a>
</div>
</td>
</tr>
{% endfor %} {% else %}
......@@ -39,6 +55,7 @@
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
{% endif %}
</tbody>
......
......@@ -10,8 +10,8 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""
import os
from pathlib import Path
from os import getenv
from dotenv import load_dotenv
# Build paths inside the project like this: BASE_DIR / 'subdir'.
......@@ -19,7 +19,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# .env
load_dotenv()
JWT_SECRET = getenv("JWT_SECRET", default="")
JWT_SECRET = os.getenv("JWT_SECRET", default="")
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
......@@ -104,6 +104,8 @@ TEMPLATES = [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"django.template.context_processors.media",
# local
"authentications.context_processors.get_auth_session",
],
},
......@@ -119,11 +121,11 @@ WSGI_APPLICATION = "config.wsgi.application"
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": getenv("DB_NAME"),
"USER": getenv("DB_USER"),
"PASSWORD": getenv("DB_PASSWORD"),
"HOST": getenv("DB_HOST"),
"PORT": getenv("DB_PORT"),
"NAME": os.getenv("DB_NAME"),
"USER": os.getenv("DB_USER"),
"PASSWORD": os.getenv("DB_PASSWORD"),
"HOST": os.getenv("DB_HOST"),
"PORT": os.getenv("DB_PORT"),
}
}
......@@ -162,12 +164,18 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
STATIC_URL = "static/"
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
},
}
......
......@@ -15,10 +15,12 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
from dashboards.views import HomePage
from django.conf.urls.static import static
urlpatterns = [
path("", HomePage.as_view(), name="homepage"),
......@@ -35,3 +37,6 @@ urlpatterns = [
),
path("api-auth/", include("rest_framework.urls")),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
......@@ -2,7 +2,7 @@
<div style="max-width: 80vw" class="w-100 p-4">
<div class="d-flex flex-column gap-2 mb-4">
<h1 class="h3">Add Data</h1>
<form action="" method="POST">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="d-flex flex-column gap-1">{{ form }}</div>
<div class="d-flex gap-2 my-3">
......
......@@ -2,7 +2,7 @@
<div style="max-width: 80vw" class="w-100 p-4">
<div class="d-flex flex-column gap-2 mb-4">
<h1 class="h3">Are you sure want to delete this data
<form action="" method="POST">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="d-flex flex-column gap-1">Once data is deleted, it cannot be restored.</div>
<div class="d-flex gap-2 my-3">
......
......@@ -2,7 +2,7 @@
<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 action="" method="POST">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="d-flex flex-column gap-1">{{ form }}</div>
<div class="d-flex gap-2 my-3">
......
# Generated by Django 5.0.6 on 2024-07-10 02:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('members', '0007_alter_members_account_number'),
]
operations = [
migrations.AlterField(
model_name='members',
name='account_number',
field=models.CharField(default='190415015691257', editable=False, max_length=15),
),
]
# Generated by Django 5.0.6 on 2024-07-10 04:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('members', '0008_alter_members_account_number'),
]
operations = [
migrations.AlterField(
model_name='members',
name='account_number',
field=models.CharField(default='022569062908676', editable=False, max_length=15),
),
]
# Generated by Django 5.0.6 on 2024-07-10 05:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('members', '0009_alter_members_account_number'),
]
operations = [
migrations.AlterField(
model_name='members',
name='account_number',
field=models.CharField(default='955979555055185', editable=False, max_length=15),
),
]
# Generated by Django 5.0.6 on 2024-07-10 05:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('members', '0010_alter_members_account_number'),
]
operations = [
migrations.AlterField(
model_name='members',
name='account_number',
field=models.CharField(default='574296497943013', editable=False, max_length=15),
),
]
# Generated by Django 5.0.6 on 2024-07-10 05:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('members', '0011_alter_members_account_number'),
]
operations = [
migrations.AlterField(
model_name='members',
name='account_number',
field=models.CharField(default='232120498178845', editable=False, max_length=15),
),
]
# Generated by Django 5.0.6 on 2024-07-10 05:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('members', '0012_alter_members_account_number'),
]
operations = [
migrations.AlterField(
model_name='members',
name='account_number',
field=models.CharField(default='733604449314241', editable=False, max_length=15),
),
]
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