django admin improvement complete
This commit is contained in:
@@ -5,6 +5,7 @@ from django import forms
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||
from unfold.admin import ModelAdmin, TabularInline
|
||||
from simple_history.admin import SimpleHistoryAdmin
|
||||
from igny8_core.admin.base import AccountAdminMixin, Igny8ModelAdmin
|
||||
from .models import User, Account, Plan, Subscription, Site, Sector, SiteUserAccess, Industry, IndustrySector, SeedKeyword, PasswordResetToken
|
||||
from import_export.admin import ExportMixin
|
||||
@@ -155,7 +156,7 @@ class AccountResource(resources.ModelResource):
|
||||
|
||||
|
||||
@admin.register(Account)
|
||||
class AccountAdmin(ExportMixin, AccountAdminMixin, Igny8ModelAdmin):
|
||||
class AccountAdmin(ExportMixin, AccountAdminMixin, SimpleHistoryAdmin, Igny8ModelAdmin):
|
||||
resource_class = AccountResource
|
||||
form = AccountAdminForm
|
||||
list_display = ['name', 'slug', 'owner', 'plan', 'status', 'health_indicator', 'credits', 'created_at']
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Generated by Django 5.2.9 on 2025-12-15 01:28
|
||||
|
||||
import django.core.validators
|
||||
import django.db.models.deletion
|
||||
import simple_history.models
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('igny8_core_auth', '0016_alter_plan_annual_discount_percent'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='HistoricalAccount',
|
||||
fields=[
|
||||
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
|
||||
('is_deleted', models.BooleanField(db_index=True, default=False)),
|
||||
('deleted_at', models.DateTimeField(blank=True, db_index=True, null=True)),
|
||||
('restore_until', models.DateTimeField(blank=True, db_index=True, null=True)),
|
||||
('delete_reason', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('slug', models.SlugField(max_length=255)),
|
||||
('stripe_customer_id', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('credits', models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0)])),
|
||||
('status', models.CharField(choices=[('active', 'Active'), ('suspended', 'Suspended'), ('trial', 'Trial'), ('cancelled', 'Cancelled'), ('pending_payment', 'Pending Payment')], default='trial', max_length=20)),
|
||||
('payment_method', models.CharField(choices=[('stripe', 'Stripe'), ('paypal', 'PayPal'), ('bank_transfer', 'Bank Transfer')], default='stripe', help_text='Payment method used for this account', max_length=30)),
|
||||
('deletion_retention_days', models.PositiveIntegerField(default=14, help_text='Retention window (days) before soft-deleted items are purged', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(365)])),
|
||||
('billing_email', models.EmailField(blank=True, help_text='Email for billing notifications', max_length=254, null=True)),
|
||||
('billing_address_line1', models.CharField(blank=True, help_text='Street address', max_length=255)),
|
||||
('billing_address_line2', models.CharField(blank=True, help_text='Apt, suite, etc.', max_length=255)),
|
||||
('billing_city', models.CharField(blank=True, max_length=100)),
|
||||
('billing_state', models.CharField(blank=True, help_text='State/Province/Region', max_length=100)),
|
||||
('billing_postal_code', models.CharField(blank=True, max_length=20)),
|
||||
('billing_country', models.CharField(blank=True, help_text='ISO 2-letter country code', max_length=2)),
|
||||
('tax_id', models.CharField(blank=True, help_text='VAT/Tax ID number', max_length=100)),
|
||||
('usage_content_ideas', models.IntegerField(default=0, help_text='Content ideas generated this month', validators=[django.core.validators.MinValueValidator(0)])),
|
||||
('usage_content_words', models.IntegerField(default=0, help_text='Content words generated this month', validators=[django.core.validators.MinValueValidator(0)])),
|
||||
('usage_images_basic', models.IntegerField(default=0, help_text='Basic AI images this month', validators=[django.core.validators.MinValueValidator(0)])),
|
||||
('usage_images_premium', models.IntegerField(default=0, help_text='Premium AI images this month', validators=[django.core.validators.MinValueValidator(0)])),
|
||||
('usage_image_prompts', models.IntegerField(default=0, help_text='Image prompts this month', validators=[django.core.validators.MinValueValidator(0)])),
|
||||
('usage_period_start', models.DateTimeField(blank=True, help_text='Current billing period start', null=True)),
|
||||
('usage_period_end', models.DateTimeField(blank=True, help_text='Current billing period end', null=True)),
|
||||
('created_at', models.DateTimeField(blank=True, editable=False)),
|
||||
('updated_at', models.DateTimeField(blank=True, editable=False)),
|
||||
('history_id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('history_date', models.DateTimeField(db_index=True)),
|
||||
('history_change_reason', models.CharField(max_length=100, null=True)),
|
||||
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
|
||||
('deleted_by', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||
('owner', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||
('plan', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='igny8_core_auth.plan')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'historical Account',
|
||||
'verbose_name_plural': 'historical Accounts',
|
||||
'ordering': ('-history_date', '-history_id'),
|
||||
'get_latest_by': ('history_date', 'history_id'),
|
||||
},
|
||||
bases=(simple_history.models.HistoricalChanges, models.Model),
|
||||
),
|
||||
]
|
||||
@@ -6,6 +6,7 @@ from django.contrib.auth.models import AbstractUser
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||
from igny8_core.common.soft_delete import SoftDeletableModel, SoftDeleteManager
|
||||
from simple_history.models import HistoricalRecords
|
||||
|
||||
|
||||
class AccountBaseModel(models.Model):
|
||||
@@ -117,6 +118,9 @@ class Account(SoftDeletableModel):
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
# History tracking
|
||||
history = HistoricalRecords()
|
||||
|
||||
class Meta:
|
||||
db_table = 'igny8_tenants'
|
||||
|
||||
Reference in New Issue
Block a user