initialize project documentation and setup instructions
This commit is contained in:
0
apps/core/__init__.py
Normal file
0
apps/core/__init__.py
Normal file
3
apps/core/admin.py
Normal file
3
apps/core/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
5
apps/core/apps.py
Normal file
5
apps/core/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class CoreConfig(AppConfig):
|
||||
name = 'apps.core'
|
||||
19
apps/core/context_processors.py
Normal file
19
apps/core/context_processors.py
Normal 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': '© 2026 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
34
apps/core/forms.py
Normal 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'
|
||||
})
|
||||
45
apps/core/migrations/0001_initial.py
Normal file
45
apps/core/migrations/0001_initial.py
Normal 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()),
|
||||
],
|
||||
),
|
||||
]
|
||||
0
apps/core/migrations/__init__.py
Normal file
0
apps/core/migrations/__init__.py
Normal file
7
apps/core/models.py
Normal file
7
apps/core/models.py
Normal 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)
|
||||
65
apps/core/templatetags/custom_filters.py
Executable file
65
apps/core/templatetags/custom_filters.py
Executable 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
3
apps/core/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
13
apps/core/urls.py
Normal file
13
apps/core/urls.py
Normal 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
39
apps/core/views.py
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user