initialize project documentation and setup instructions

This commit is contained in:
itsmeabimanyu
2026-03-01 07:03:16 +07:00
parent df7071f519
commit 6fdf9d5b62
146 changed files with 89855 additions and 1 deletions

0
apps/core/__init__.py Normal file
View File

3
apps/core/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
apps/core/apps.py Normal file
View File

@@ -0,0 +1,5 @@
from django.apps import AppConfig
class CoreConfig(AppConfig):
name = 'apps.core'

View File

@@ -0,0 +1,19 @@
def titles(request):
name_apps = "FLN Django Template"
version = 'v1.0.0'
return {
'name_apps': name_apps,
'alt_name_apps': 'FLN Django Template',
'brand_copyright': '&copy; 2026&ensp;IT Frina Lestari Nusantara, Inc.<br>All rights reserved.',
'brand': 'PT. Frina Lestari Nusantara',
'it_support_email': 'support@fln.co.id',
'repository': f"""
<p class="mb-1" style="font-size: 0.8rem;">
<a href="https://github.com/itsmeabimanyu/fln-django-template" target="_blank" class="text-decoration-none text-muted">
<i class="ri-github-fill me-1 fs-6"></i>{name_apps} <span class="opacity-75">{version}</span>
</a>
</p>
""",
'version': version,
}

34
apps/core/forms.py Normal file
View File

@@ -0,0 +1,34 @@
from .models import CustomUserLogin
from django.contrib.auth.forms import UserCreationForm
class RegisterForm(UserCreationForm):
class Meta:
model = CustomUserLogin
fields = ['username', 'first_name', 'last_name', 'email']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
placeholders = {
'username': 'Choose a unique username',
'first_name': 'Enter your first name',
'last_name': 'Enter your last name (optional)',
'email': 'example@email.com',
'password1': 'Create a strong password',
'password2': 'Repeat your password',
}
for field_name, field in self.fields.items():
if field_name == 'last_name':
field.required = False
else:
field.required = True
if field_name in placeholders:
field.widget.attrs.update({'placeholder': placeholders[field_name]})
field.widget.attrs.update({
'class': 'form-control mt-2 mb-2',
'autocomplete': 'off'
})

View File

@@ -0,0 +1,45 @@
# Generated by Django 6.0.2 on 2026-02-28 07:07
import django.contrib.auth.models
import django.contrib.auth.validators
import django.utils.timezone
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='CustomUserLogin',
fields=[
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
]

View File

7
apps/core/models.py Normal file
View File

@@ -0,0 +1,7 @@
import uuid
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class CustomUserLogin(AbstractUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

View File

@@ -0,0 +1,65 @@
from django import template
from urllib.parse import quote_plus
from django.db.models.fields.files import FieldFile
from django.utils.dateformat import format
import datetime, os
import base64
register = template.Library()
@register.filter
def get_field_value(obj, attr_name):
# Ambil nilai dari dict atau objek
if isinstance(obj, dict):
value = obj.get(attr_name, None)
else:
value = getattr(obj, attr_name, None)
# 1. Handle None atau String Kosong (Hanya spasi)
if value is None:
return "--"
if isinstance(value, str):
if not value.strip():
return "--"
return value # Kembalikan nilai asli (Nama@Mail.Com tetap Nama@Mail.Com)
# 2. Handle ManyToManyField (RelatedManager)
if hasattr(value, 'all'):
queryset = value.all()
if queryset.exists():
return ', '.join(str(item) for item in queryset)
return "--"
# 3. Handle Files (Hanya ambil nama filenya saja)
if isinstance(value, FieldFile):
return os.path.basename(value.name) if value else "--"
# 4. Handle Datetime & Date
if isinstance(value, datetime.datetime):
return value.strftime('%d/%m/%Y %H:%M')
if isinstance(value, datetime.date):
return value.strftime('%d-%b-%Y')
# 5. Handle Boolean
if isinstance(value, bool):
return 'Active' if value else 'Inactive'
return value
@register.filter
def plural(value):
if not isinstance(value, str):
return value
words = value.strip().split()
last_word = words[-1]
if last_word.endswith('y') and not last_word.endswith(('ay', 'ey', 'iy', 'oy', 'uy')):
last_word = last_word[:-1] + 'ies'
elif not last_word.endswith('s'):
last_word = last_word + 's'
words[-1] = last_word
return ' '.join(words)

3
apps/core/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

13
apps/core/urls.py Normal file
View File

@@ -0,0 +1,13 @@
from django.urls import path
from django.shortcuts import redirect
from . import views
handler404 = views.Template404View.as_view()
urlpatterns = [
path('403/', views.Template403View.as_view(), name='403_view'),
path('logout/', views.LogoutView.as_view(), name='logout'),
path('', lambda request: redirect('dashboard')),
path('dashboard/', views.DashboardView.as_view(), name='dashboard'),
path('form/', views.FormView.as_view(), name='form'),
]

39
apps/core/views.py Normal file
View File

@@ -0,0 +1,39 @@
from django.shortcuts import render
from django.views.generic import TemplateView, View, CreateView
from .models import CustomUserLogin
from .forms import RegisterForm
# Create your views here.
class Template403View(TemplateView):
template_name = "403.html"
class Template404View(TemplateView):
template_name = "404.html"
class LogoutView(View):
def get(self, request, *args, **kwargs):
request.session.flush()
return redirect(settings.LOGOUT_REDIRECT_URL)
class DashboardView(TemplateView):
template_name = "pages/dashboard.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["menu"] = "Dashboard"
return context
class FormView(CreateView):
template_name = "pages/form.html"
model = CustomUserLogin
form_class = RegisterForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["menu"] = "Dashboard"
context["card_form"] = "Register Form"
context["card_list"] = "List View"
context["items"] = self.model.objects.all()
return context