Step-by-Step Guide to Create the order_management App
1. Create the Django App
Run the following command in your Django project directory to create the new app:
python manage.py startapp order_managementThis will generate a directory named order_management with the basic structure.
2. Define the Models
Place the models in order_management/models.py. These are based on the tables you provided (Buyer, Order, Order Breakdown, Tech Pack, Delivery Schedule).
from django.db import models
from django.utils.translation import gettext_lazy as _
# Buyer Model
class Buyer(models.Model):
name = models.CharField(max_length=100, verbose_name=_("Buyer Name"))
country = models.CharField(max_length=100, verbose_name=_("Country"))
contact_person = models.CharField(max_length=100, verbose_name=_("Contact Person"))
phone = models.CharField(max_length=20, verbose_name=_("Phone"))
email = models.EmailField(verbose_name=_("Email"))
class Meta:
verbose_name = _("Buyer")
verbose_name_plural = _("Buyers")
def __str__(self):
return self.name
# Order Model
class Order(models.Model):
STATUS_CHOICES = (
('received', _('Received')),
('processing', _('Processing')),
('completed', _('Completed')),
('cancelled', _('Cancelled')),
)
buyer = models.ForeignKey(Buyer, on_delete=models.CASCADE, verbose_name=_("Buyer"))
style_number = models.CharField(max_length=50, verbose_name=_("Style Number"))
season = models.CharField(max_length=50, verbose_name=_("Season"))
order_date = models.DateField(verbose_name=_("Order Date"))
delivery_deadline = models.DateField(verbose_name=_("Delivery Deadline"))
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='received', verbose_name=_("Status"))
remarks = models.TextField(blank=True, verbose_name=_("Remarks"))
class Meta:
verbose_name = _("Order")
verbose_name_plural = _("Orders")
def __str__(self):
return f"{self.style_number} ({self.buyer.name})"
# Order Breakdown Model
class OrderBreakdown(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name=_("Order"))
size = models.CharField(max_length=10, verbose_name=_("Size"))
color = models.CharField(max_length=50, verbose_name=_("Color"))
quantity = models.PositiveIntegerField(verbose_name=_("Quantity"))
class Meta:
verbose_name = _("Order Breakdown")
verbose_name_plural = _("Order Breakdowns")
def __str__(self):
return f"{self.order.style_number} - {self.size} ({self.color})"
# Tech Pack Model
class TechPack(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name=_("Order"))
file_name = models.CharField(max_length=200, verbose_name=_("File Name"))
uploaded_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Uploaded At"))
file = models.FileField(upload_to='techpacks/', blank=True, null=True, verbose_name=_("Tech Pack File"))
class Meta:
verbose_name = _("Tech Pack")
verbose_name_plural = _("Tech Packs")
def __str__(self):
return f"{self.file_name} ({self.order.style_number})"
# Delivery Schedule Model
class DeliverySchedule(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name=_("Order"))
delivery_date = models.DateField(verbose_name=_("Delivery Date"))
quantity = models.PositiveIntegerField(verbose_name=_("Quantity"))
remarks = models.TextField(blank=True, verbose_name=_("Remarks"))
class Meta:
verbose_name = _("Delivery Schedule")
verbose_name_plural = _("Delivery Schedules")
def __str__(self):
return f"{self.order.style_number} - {self.delivery_date}"3. Register Models in Admin
Create or update order_management/admin.py to register the models with Unfold Admin, ensuring a user-friendly interface.
from django.contrib import admin
from unfold.admin import ModelAdmin
from .models import Buyer, Order, OrderBreakdown, TechPack, DeliverySchedule
from django.utils.translation import gettext_lazy as _
# Register Buyer model
@admin.register(Buyer)
class BuyerAdmin(ModelAdmin):
list_display = ('name', 'country', 'contact_person', 'phone', 'email')
search_fields = ('name', 'country', 'contact_person', 'email')
list_filter = ('country',)
ordering = ('name',)
# Register Order model
@admin.register(Order)
class OrderAdmin(ModelAdmin):
list_display = ('style_number', 'buyer', 'season', 'order_date', 'delivery_deadline', 'status')
search_fields = ('style_number', 'buyer__name', 'season')
list_filter = ('status', 'season', 'order_date')
ordering = ('-order_date',)
# Register OrderBreakdown model
@admin.register(OrderBreakdown)
class OrderBreakdownAdmin(ModelAdmin):
list_display = ('order', 'size', 'color', 'quantity')
search_fields = ('order__style_number', 'size', 'color')
list_filter = ('size', 'color')
ordering = ('order',)
# Register TechPack model
@admin.register(TechPack)
class TechPackAdmin(ModelAdmin):
list_display = ('order', 'file_name', 'uploaded_at')
search_fields = ('order__style_number', 'file_name')
list_filter = ('uploaded_at',)
ordering = ('-uploaded_at',)
# Register DeliverySchedule model
@admin.register(DeliverySchedule)
class DeliveryScheduleAdmin(ModelAdmin):
list_display = ('order', 'delivery_date', 'quantity', 'remarks')
search_fields = ('order__style_number', 'remarks')
list_filter = ('delivery_date',)
ordering = ('delivery_date',)4. Update settings.py for Unfold Sidebar
Update your project’s settings.py to include the order_management app in INSTALLED_APPS and add the models to the Unfold sidebar. Replace your_app_name with order_management in the sidebar configuration.
from django.templatetags.static import static
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
INSTALLED_APPS = [
'unfold',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'order_management', # Add the new app
# ... other apps
]
# Media settings for file uploads
MEDIA_URL = '/media/'
MEDIA_ROOT = 'media'
UNFOLD = {
"SITE_TITLE": "Kreatech Erp",
"SITE_HEADER": "Kreatech Erp",
"SITE_LOGO": static("path/to/your/custom-logo.svg"),
"SITE_URL": "/",
"SHOW_HISTORY": False,
"SIDEBAR": {
"show_search": True,
"show_all_applications": False,
"navigation": [
{
"title": _("Data And Analytics"),
"separator": True,
"collapsible": True,
"items": [
{
"title": _("Dashboard"),
"icon": "dashboard",
"link": reverse_lazy("admin:index"),
"permission": lambda request: request.user.is_superuser,
},
],
},
{
"title": _("Authentication"),
"separator": True,
"collapsible": True,
"items": [
{
"title": _("Users"),
"icon": "people",
"link": reverse_lazy("admin:auth_user_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Groups"),
"icon": "group",
"link": reverse_lazy("admin:auth_group_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Permissions"),
"icon": "lock",
"link": reverse_lazy("admin:auth_permission_changelist"),
"permission": lambda request: request.user.is_superuser,
},
],
},
{
"title": _("Order Management"),
"separator": True,
"collapsible": True,
"items": [
{
"title": _("Buyers"),
"icon": "business",
"link": reverse_lazy("admin:order_management_buyer_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Orders"),
"icon": "shopping_cart",
"link": reverse_lazy("admin:order_management_order_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Order Breakdowns"),
"icon": "list_alt",
"link": reverse_lazy("admin:order_management_orderbreakdown_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Tech Packs"),
"icon": "description",
"link": reverse_lazy("admin:order_management_techpack_changelist"),
"permission": lambda request: request.user.is_superuser,
},
{
"title": _("Delivery Schedules"),
"icon": "local_shipping",
"link": reverse_lazy("admin:order_management_deliveryschedule_changelist"),
"permission": lambda request: request.user.is_superuser,
},
],
},
],
},
}5. Configure URLs
Ensure your project’s urls.py includes the admin URLs. This is typically already set up, but here’s an example for completeness:
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)6. Create Media Directory
Since the TechPack model includes a FileField for uploading tech pack files, create a media/techpacks/ directory in your project root to store uploaded files:
mkdir -p media/techpacksEnsure your Django project is configured to serve media files during development by adding the media URL mapping in urls.py (as shown above).
7. Run Migrations
Generate and apply migrations to create the database tables for the new models:
python manage.py makemigrations
python manage.py migrate8. Test the Admin Interface
- Start the Django development server:
python manage.py runserver- Log in to the admin panel at
http://localhost:8000/admin/(or your configured URL). - Verify that the “Order Management” section appears in the Unfold sidebar with links to Buyers, Orders, Order Breakdowns, Tech Packs, and Delivery Schedules.
- Test adding data (e.g., a Buyer like H&M, an Order with style number TWL-HM-2025, etc.) to ensure the models work as expected.
To test with the sample data from your story, you can manually add the data via the admin interface or use a Django management command. Here’s an example management command to populate the sample data:
from django.core.management.base import BaseCommand
from order_management.models import Buyer, Order, OrderBreakdown, TechPack, DeliverySchedule
from django.utils import timezone
class Command(BaseCommand):
help = 'Populates sample data for the Order Management module'
def handle(self, *args, **kwargs):
# Create Buyer
buyer = Buyer.objects.create(
name="H&M",
country="Sweden",
contact_person="John Smith",
phone="+467890",
email="john@hm.com"
)
# Create Order
order = Order.objects.create(
buyer=buyer,
style_number="TWL-HM-2025",
season="Winter",
order_date="2025-08-01",
delivery_deadline="2025-09-30",
status="received",
remarks="urgent order"
)
# Create Order Breakdowns
OrderBreakdown.objects.create(order=order, size="M", color="Navy", quantity=4000)
OrderBreakdown.objects.create(order=order, size="L", color="Black", quantity=3000)
OrderBreakdown.objects.create(order=order, size="S", color="White", quantity=3000)
# Create Tech Pack
TechPack.objects.create(
order=order,
file_name="TWL-HM-2025-techpack.pdf",
uploaded_at=timezone.now()
)
# Create Delivery Schedules
DeliverySchedule.objects.create(
order=order,
delivery_date="2025-09-15",
quantity=5000,
remarks="First Shipment"
)
DeliverySchedule.objects.create(
order=order,
delivery_date="2025-09-30",
quantity=5000,
remarks="Final Shipment"
)
self.stdout.write(self.style.SUCCESS('Sample data populated successfully!'))
To use this command, run:
python manage.py populate_sample_data
This will populate the database with the exact data from your story (e.g., H&M’s order for 10,000 T-shirts).
Additional Notes
- App Structure: The
order_managementapp is now fully functional with models, admin integration, and Unfold sidebar configuration. The models reflect the workflow you described (Buyer → Order → Order Breakdown → Tech Pack → Delivery Schedule). - Media Handling: Ensure
MEDIA_ROOTandMEDIA_URLare correctly configured insettings.py, and the server has write permissions to themedia/techpacks/directory. - Permissions: The sidebar links are restricted to superusers (
request.user.is_superuser). You can modify thepermissionlambda functions inUNFOLDto support other user roles if needed. - Next Steps: If you want to proceed with the Fabric Requirement Planning + Procurement Module, I can create another app (e.g.,
procurement) with models for fabric and trims requirements, procurement workflows, and integration into the Unfold sidebar. Let me know if you’d like me to implement this with a similar storytelling approach, tables, and Django models.
Would you like me to:
- Create the
procurementapp for fabric requirement planning? - Add additional features to the
order_managementapp (e.g., custom views, reports, or filters)? - Provide further customization for the Unfold admin interface?