Initial commit
This commit is contained in:
0
plans/__init__.py
Normal file
0
plans/__init__.py
Normal file
BIN
plans/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
plans/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
plans/__pycache__/admin.cpython-312.pyc
Normal file
BIN
plans/__pycache__/admin.cpython-312.pyc
Normal file
Binary file not shown.
BIN
plans/__pycache__/apps.cpython-312.pyc
Normal file
BIN
plans/__pycache__/apps.cpython-312.pyc
Normal file
Binary file not shown.
BIN
plans/__pycache__/models.cpython-312.pyc
Normal file
BIN
plans/__pycache__/models.cpython-312.pyc
Normal file
Binary file not shown.
BIN
plans/__pycache__/tests.cpython-312.pyc
Normal file
BIN
plans/__pycache__/tests.cpython-312.pyc
Normal file
Binary file not shown.
BIN
plans/__pycache__/urls.cpython-312.pyc
Normal file
BIN
plans/__pycache__/urls.cpython-312.pyc
Normal file
Binary file not shown.
BIN
plans/__pycache__/views.cpython-312.pyc
Normal file
BIN
plans/__pycache__/views.cpython-312.pyc
Normal file
Binary file not shown.
18
plans/admin.py
Normal file
18
plans/admin.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from django.contrib import admin
|
||||
from .models import Plan
|
||||
|
||||
|
||||
@admin.register(Plan)
|
||||
class PlanAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'name',
|
||||
'base_price_per_domain',
|
||||
'included_traffic_gb_per_domain',
|
||||
'overage_price_per_gb',
|
||||
'is_active',
|
||||
'is_public',
|
||||
'updated_at',
|
||||
)
|
||||
search_fields = ('name',)
|
||||
|
||||
# Register your models here.
|
||||
6
plans/apps.py
Normal file
6
plans/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PlansConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'plans'
|
||||
38
plans/migrations/0001_initial.py
Normal file
38
plans/migrations/0001_initial.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# Generated by Django 5.2.8 on 2025-11-07 07:39
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Plan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=50, unique=True)),
|
||||
('description', models.TextField(blank=True, default='')),
|
||||
('billing_mode', models.CharField(default='per_domain_monthly', max_length=50)),
|
||||
('base_price_per_domain', models.DecimalField(decimal_places=2, default=0, max_digits=10)),
|
||||
('included_traffic_gb_per_domain', models.PositiveIntegerField(default=0)),
|
||||
('overage_price_per_gb', models.DecimalField(decimal_places=2, default=0, max_digits=10)),
|
||||
('allow_overage', models.BooleanField(default=True)),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
('is_public', models.BooleanField(default=True)),
|
||||
('allow_new_purchase', models.BooleanField(default=True)),
|
||||
('allow_renew', models.BooleanField(default=True)),
|
||||
('features', models.JSONField(blank=True, default=dict)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '套餐',
|
||||
'verbose_name_plural': '套餐',
|
||||
},
|
||||
),
|
||||
]
|
||||
0
plans/migrations/__init__.py
Normal file
0
plans/migrations/__init__.py
Normal file
BIN
plans/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
BIN
plans/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
Binary file not shown.
BIN
plans/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
plans/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
27
plans/models.py
Normal file
27
plans/models.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Plan(models.Model):
|
||||
name = models.CharField(max_length=50, unique=True)
|
||||
description = models.TextField(blank=True, default='')
|
||||
billing_mode = models.CharField(max_length=50, default='per_domain_monthly')
|
||||
base_price_per_domain = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
||||
included_traffic_gb_per_domain = models.PositiveIntegerField(default=0)
|
||||
overage_price_per_gb = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
||||
allow_overage = models.BooleanField(default=True)
|
||||
is_active = models.BooleanField(default=True)
|
||||
is_public = models.BooleanField(default=True)
|
||||
allow_new_purchase = models.BooleanField(default=True)
|
||||
allow_renew = models.BooleanField(default=True)
|
||||
features = models.JSONField(default=dict, blank=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '套餐'
|
||||
verbose_name_plural = '套餐'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
# Create your models here.
|
||||
3
plans/tests.py
Normal file
3
plans/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
6
plans/urls.py
Normal file
6
plans/urls.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.list_plans, name='list'),
|
||||
]
|
||||
12
plans/views.py
Normal file
12
plans/views.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from django.shortcuts import render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from .models import Plan
|
||||
|
||||
|
||||
@login_required
|
||||
def list_plans(request):
|
||||
plans = Plan.objects.filter(is_active=True, is_public=True).order_by('base_price_per_domain')
|
||||
return render(request, 'plans/list.html', {
|
||||
'plans': plans,
|
||||
})
|
||||
Reference in New Issue
Block a user