use dry principle possible and added example project
This commit is contained in:
46 files changed
+3521
-772
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,42 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from django_nepkit import NepaliModelAdmin
|
||||
|
||||
from .models import Person
|
||||
|
||||
|
||||
@admin.register(Person)
|
||||
class PersonAdmin(NepaliModelAdmin):
|
||||
list_display = (
|
||||
"name",
|
||||
"display_birth_date",
|
||||
"phone_number",
|
||||
"province",
|
||||
"district",
|
||||
"municipality",
|
||||
"display_created_at",
|
||||
"display_updated_at",
|
||||
)
|
||||
list_filter = ("birth_date", "province", "district")
|
||||
search_fields = ("name", "phone_number")
|
||||
|
||||
def display_birth_date(self, obj):
|
||||
"""Display birth date with Nepali month names"""
|
||||
return self.format_nepali_date(obj.birth_date)
|
||||
|
||||
display_birth_date.short_description = "Birth Date"
|
||||
display_birth_date.admin_order_field = "birth_date"
|
||||
|
||||
def display_created_at(self, obj):
|
||||
"""Display created date with Nepali month names"""
|
||||
return self.format_nepali_datetime(obj.created_at)
|
||||
|
||||
display_created_at.short_description = "Created At"
|
||||
display_created_at.admin_order_field = "created_at"
|
||||
|
||||
def display_updated_at(self, obj):
|
||||
"""Display updated date with Nepali month names"""
|
||||
return self.format_nepali_datetime(obj.updated_at)
|
||||
|
||||
display_updated_at.short_description = "Updated At"
|
||||
display_updated_at.admin_order_field = "updated_at"
|
||||
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class DemoConfig(AppConfig):
|
||||
name = "demo"
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 6.0.1 on 2026-01-28 15:37
|
||||
|
||||
import django_nepkit.models
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("demo", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="person",
|
||||
name="phone_number",
|
||||
field=django_nepkit.models.NepaliPhoneNumberField(max_length=10),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 6.0.1 on 2026-01-28 15:38
|
||||
|
||||
import django.utils.timezone
|
||||
import django_nepkit.models
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("demo", "0002_alter_person_phone_number"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="person",
|
||||
name="created_at",
|
||||
field=django_nepkit.models.NepaliTimeField(
|
||||
auto_now_add=True, default=django.utils.timezone.now
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="person",
|
||||
name="updated_at",
|
||||
field=django_nepkit.models.NepaliTimeField(auto_now=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 6.0.1 on 2026-01-28 15:39
|
||||
|
||||
import django_nepkit.models
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("demo", "0003_person_created_at_person_updated_at"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="person",
|
||||
name="created_at",
|
||||
field=django_nepkit.models.NepaliDateField(auto_now_add=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="person",
|
||||
name="updated_at",
|
||||
field=django_nepkit.models.NepaliDateField(auto_now=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 6.0.1 on 2026-01-28 16:55
|
||||
|
||||
import django_nepkit.models
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("demo", "0004_alter_person_created_at_alter_person_updated_at"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="person",
|
||||
name="created_at",
|
||||
field=django_nepkit.models.NepaliDateTimeField(
|
||||
auto_now_add=True, blank=True, editable=False, max_length=19
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="person",
|
||||
name="updated_at",
|
||||
field=django_nepkit.models.NepaliDateTimeField(
|
||||
auto_now=True, blank=True, editable=False, max_length=19
|
||||
),
|
||||
),
|
||||
]
|
||||
Whitespace-only changes.
@@ -0,0 +1,27 @@
|
||||
from django.db import models
|
||||
from django_nepkit import (
|
||||
NepaliDateField,
|
||||
NepaliTimeField,
|
||||
NepaliPhoneNumberField,
|
||||
NepaliDateTimeField,
|
||||
ProvinceField,
|
||||
DistrictField,
|
||||
MunicipalityField,
|
||||
)
|
||||
|
||||
|
||||
class Person(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
birth_date = NepaliDateField()
|
||||
registration_time = NepaliTimeField(auto_now_add=True)
|
||||
phone_number = NepaliPhoneNumberField()
|
||||
|
||||
# Address chaining
|
||||
province = ProvinceField()
|
||||
district = DistrictField()
|
||||
municipality = MunicipalityField()
|
||||
created_at = NepaliDateTimeField(auto_now_add=True)
|
||||
updated_at = NepaliDateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Nepali Fields Demo - Add</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; margin: 20px; }
|
||||
.form-group { margin-bottom: 15px; }
|
||||
label { display: block; margin-bottom: 5px; }
|
||||
input, select { width: 300px; padding: 8px; }
|
||||
</style>
|
||||
{{ form.media }}
|
||||
</head>
|
||||
<body>
|
||||
<h1>Add New Person</h1>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% for field in form %}
|
||||
<div class="form-group">
|
||||
{{ field.label_tag }}
|
||||
{{ field }}
|
||||
{% if field.help_text %}
|
||||
<small style="color: grey">{{ field.help_text }}</small>
|
||||
{% endif %}
|
||||
{% for error in field.errors %}
|
||||
<p style="color: red">{{ error }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<button type="submit">Save</button>
|
||||
</form>
|
||||
<br>
|
||||
<a href="{% url 'demo:person-list' %}">Back to List</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,48 @@
|
||||
{% load nepali %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Nepali Fields Demo - List</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; margin: 20px; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||||
th { background-color: #f2f2f2; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Person List</h1>
|
||||
<a href="{% url 'demo:person-create' %}">Add New Person</a>
|
||||
<hr>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Birth Date (BS)</th>
|
||||
<th>Birth Date (Devanagari)</th>
|
||||
<th>Phone</th>
|
||||
<th>Province</th>
|
||||
<th>District</th>
|
||||
<th>Municipality</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for person in persons %}
|
||||
<tr>
|
||||
<td>{{ person.name }}</td>
|
||||
<td>{{ person.birth_date|nepali_date }}</td>
|
||||
<td>{{ person.birth_date|nepali_date_ne }}</td>
|
||||
<td>{{ person.phone_number }}</td>
|
||||
<td>{{ person.province }}</td>
|
||||
<td>{{ person.district }}</td>
|
||||
<td>{{ person.municipality }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="7">No records found.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
# Create your tests here.
|
||||
@@ -0,0 +1,9 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
app_name = "demo"
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.person_list, name="person-list"),
|
||||
path("add/", views.person_create, name="person-create"),
|
||||
]
|
||||
@@ -0,0 +1,32 @@
|
||||
from django.shortcuts import render, redirect
|
||||
from .models import Person
|
||||
from django import forms
|
||||
|
||||
|
||||
class PersonForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Person
|
||||
fields = [
|
||||
"name",
|
||||
"birth_date",
|
||||
"phone_number",
|
||||
"province",
|
||||
"district",
|
||||
"municipality",
|
||||
]
|
||||
|
||||
|
||||
def person_list(request):
|
||||
persons = Person.objects.all()
|
||||
return render(request, "demo/person_list.html", {"persons": persons})
|
||||
|
||||
|
||||
def person_create(request):
|
||||
if request.method == "POST":
|
||||
form = PersonForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect("demo:person-list")
|
||||
else:
|
||||
form = PersonForm()
|
||||
return render(request, "demo/person_form.html", {"form": form})
|
||||
Whitespace-only changes.
@@ -0,0 +1,76 @@
|
||||
from pathlib import Path
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
SECRET_KEY = "django-insecure-#=02g9%#k0t!(0968j4f#=+u%l-ws3nfti*0n601@n_zo(&x%w"
|
||||
DEBUG = True
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"django_nepkit",
|
||||
"demo",
|
||||
]
|
||||
|
||||
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 = "example_project.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = "example_project.wsgi.application"
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": BASE_DIR / "db.sqlite3",
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
},
|
||||
]
|
||||
|
||||
LANGUAGE_CODE = "en-us"
|
||||
TIME_ZONE = "Asia/Kathmandu"
|
||||
USE_I18N = True
|
||||
USE_TZ = True
|
||||
|
||||
STATIC_URL = "static/"
|
||||
@@ -0,0 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("nepkit/", include("django_nepkit.urls")),
|
||||
path("", include("demo.urls")),
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings")
|
||||
|
||||
application = get_wsgi_application()
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.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()
|
||||
Reference in new issue
Block a user