🌐 AI搜索 & 代理 主页
Skip to content
29 changes: 26 additions & 3 deletions sponsors/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.template import Context, Template
from django.contrib import admin
from django.contrib.humanize.templatetags.humanize import intcomma
from django.forms import ModelForm
from django.urls import path, reverse, resolve
from django.utils.functional import cached_property
from django.utils.html import mark_safe
Expand Down Expand Up @@ -46,7 +47,14 @@ class SponsorshipProgramAdmin(OrderedModelAdmin):
]


class MultiPartForceForm(ModelForm):
def is_multipart(self):
return True


class BenefitFeatureConfigurationInline(StackedPolymorphicInline):
form = MultiPartForceForm

class LogoPlacementConfigurationInline(StackedPolymorphicInline.Child):
model = LogoPlacementConfiguration

Expand All @@ -60,23 +68,38 @@ class EmailTargetableConfigurationInline(StackedPolymorphicInline.Child):
def display(self, obj):
return "Enabled"

class RequiredImgAssetConfigurationInline(StackedPolymorphicInline.Child):
class BaseAssetInline(StackedPolymorphicInline.Child):

def get_readonly_fields(self, request, obj=None):
fields = list(super().get_readonly_fields(request, obj))
if obj:
fields.extend(["internal_name", "related_to"])
return fields

class RequiredImgAssetConfigurationInline(BaseAssetInline):
model = RequiredImgAssetConfiguration
form = RequiredImgAssetConfigurationForm

class RequiredTextAssetConfigurationInline(StackedPolymorphicInline.Child):
class RequiredTextAssetConfigurationInline(BaseAssetInline):
model = RequiredTextAssetConfiguration

class ProvidedTextAssetConfigurationInline(BaseAssetInline):
model = ProvidedTextAssetConfiguration

class ProvidedFileAssetConfigurationInline(BaseAssetInline):
model = ProvidedFileAssetConfiguration

model = BenefitFeatureConfiguration
child_inlines = [
LogoPlacementConfigurationInline,
TieredQuantityConfigurationInline,
EmailTargetableConfigurationInline,
RequiredImgAssetConfigurationInline,
RequiredTextAssetConfigurationInline,
ProvidedTextAssetConfigurationInline,
ProvidedFileAssetConfigurationInline,
]


@admin.register(SponsorshipBenefit)
class SponsorshipBenefitAdmin(PolymorphicInlineSupportMixin, OrderedModelAdmin):
change_form_template = "sponsors/admin/sponsorshipbenefit_change_form.html"
Expand Down
18 changes: 18 additions & 0 deletions sponsors/migrations/0068_auto_20220110_1841.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.24 on 2022-01-10 18:41

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('sponsors', '0067_sponsorbenefit_a_la_carte'),
]

operations = [
migrations.AlterField(
model_name='sponsorship',
name='for_modified_package',
field=models.BooleanField(default=False, help_text="If true, it means the user customized the package's benefits. Changes are listed under section 'User Customizations'."),
),
]
53 changes: 53 additions & 0 deletions sponsors/migrations/0069_auto_20220110_2148.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Generated by Django 2.2.24 on 2022-01-10 21:48

from django.db import migrations, models
import django.db.models.deletion
import sponsors.models.benefits


class Migration(migrations.Migration):

dependencies = [
('sponsors', '0068_auto_20220110_1841'),
]

operations = [
migrations.CreateModel(
name='ProvidedTextAsset',
fields=[
('benefitfeature_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='sponsors.BenefitFeature')),
('related_to', models.CharField(choices=[('sponsor', 'Sponsor'), ('sponsorship', 'Sponsorship')], help_text='To which instance (Sponsor or Sponsorship) should this asset relate to.', max_length=30, verbose_name='Related To')),
('internal_name', models.CharField(db_index=True, help_text='Unique name used internally to control if the sponsor/sponsorship already has the asset', max_length=128, verbose_name='Internal Name')),
('label', models.CharField(help_text="What's the title used to display the text input to the sponsor?", max_length=256)),
('help_text', models.CharField(blank=True, default='', help_text='Any helper comment on how the input should be populated', max_length=256)),
],
options={
'verbose_name': 'Provided Text',
'verbose_name_plural': 'Provided Texts',
'abstract': False,
'base_manager_name': 'objects',
},
bases=(sponsors.models.benefits.ProvidedAssetMixin, 'sponsors.benefitfeature', models.Model),
),
migrations.CreateModel(
name='ProvidedTextAssetConfiguration',
fields=[
('benefitfeatureconfiguration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='sponsors.BenefitFeatureConfiguration')),
('related_to', models.CharField(choices=[('sponsor', 'Sponsor'), ('sponsorship', 'Sponsorship')], help_text='To which instance (Sponsor or Sponsorship) should this asset relate to.', max_length=30, verbose_name='Related To')),
('internal_name', models.CharField(db_index=True, help_text='Unique name used internally to control if the sponsor/sponsorship already has the asset', max_length=128, verbose_name='Internal Name')),
('label', models.CharField(help_text="What's the title used to display the text input to the sponsor?", max_length=256)),
('help_text', models.CharField(blank=True, default='', help_text='Any helper comment on how the input should be populated', max_length=256)),
],
options={
'verbose_name': 'Provided Text Configuration',
'verbose_name_plural': 'Provided Text Configurations',
'abstract': False,
'base_manager_name': 'objects',
},
bases=(sponsors.models.benefits.AssetConfigurationMixin, 'sponsors.benefitfeatureconfiguration', models.Model),
),
migrations.AddConstraint(
model_name='providedtextassetconfiguration',
constraint=models.UniqueConstraint(fields=('internal_name',), name='uniq_provided_text_asset_cfg'),
),
]
80 changes: 80 additions & 0 deletions sponsors/migrations/0070_auto_20220111_2055.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Generated by Django 2.2.24 on 2022-01-11 20:55

from django.db import migrations, models
import django.db.models.deletion
import sponsors.models.assets
import sponsors.models.benefits


class Migration(migrations.Migration):

dependencies = [
('sponsors', '0069_auto_20220110_2148'),
]

operations = [
migrations.CreateModel(
name='FileAsset',
fields=[
('genericasset_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='sponsors.GenericAsset')),
('file', models.FileField(null=True, upload_to=sponsors.models.assets.generic_asset_path)),
],
options={
'verbose_name': 'File Asset',
'verbose_name_plural': 'File Assets',
},
bases=('sponsors.genericasset',),
),
migrations.CreateModel(
name='ProvidedFileAsset',
fields=[
('benefitfeature_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='sponsors.BenefitFeature')),
('related_to', models.CharField(choices=[('sponsor', 'Sponsor'), ('sponsorship', 'Sponsorship')], help_text='To which instance (Sponsor or Sponsorship) should this asset relate to.', max_length=30, verbose_name='Related To')),
('internal_name', models.CharField(db_index=True, help_text='Unique name used internally to control if the sponsor/sponsorship already has the asset', max_length=128, verbose_name='Internal Name')),
('shared', models.BooleanField(default=False)),
('label', models.CharField(help_text="What's the title used to display the file to the sponsor?", max_length=256)),
('help_text', models.CharField(blank=True, default='', help_text='Any helper comment on how the file should be used', max_length=256)),
('shared_file', models.FileField(blank=True, null=True, upload_to='')),
],
options={
'verbose_name': 'Provided File',
'verbose_name_plural': 'Provided Files',
'abstract': False,
'base_manager_name': 'objects',
},
bases=(sponsors.models.benefits.ProvidedAssetMixin, 'sponsors.benefitfeature', models.Model),
),
migrations.CreateModel(
name='ProvidedFileAssetConfiguration',
fields=[
('benefitfeatureconfiguration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='sponsors.BenefitFeatureConfiguration')),
('related_to', models.CharField(choices=[('sponsor', 'Sponsor'), ('sponsorship', 'Sponsorship')], help_text='To which instance (Sponsor or Sponsorship) should this asset relate to.', max_length=30, verbose_name='Related To')),
('internal_name', models.CharField(db_index=True, help_text='Unique name used internally to control if the sponsor/sponsorship already has the asset', max_length=128, verbose_name='Internal Name')),
('shared', models.BooleanField(default=False)),
('label', models.CharField(help_text="What's the title used to display the file to the sponsor?", max_length=256)),
('help_text', models.CharField(blank=True, default='', help_text='Any helper comment on how the file should be used', max_length=256)),
('shared_file', models.FileField(blank=True, null=True, upload_to='')),
],
options={
'verbose_name': 'Provided File Configuration',
'verbose_name_plural': 'Provided File Configurations',
'abstract': False,
'base_manager_name': 'objects',
},
bases=(sponsors.models.benefits.AssetConfigurationMixin, 'sponsors.benefitfeatureconfiguration', models.Model),
),
migrations.AddField(
model_name='providedtextasset',
name='shared',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='providedtextassetconfiguration',
name='shared',
field=models.BooleanField(default=False),
),
migrations.AddConstraint(
model_name='providedfileassetconfiguration',
constraint=models.UniqueConstraint(fields=('internal_name',), name='uniq_provided_file_asset_cfg'),
),
]
3 changes: 2 additions & 1 deletion sponsors/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .benefits import BaseLogoPlacement, BaseTieredQuantity, BaseEmailTargetable, BenefitFeatureConfiguration, \
LogoPlacementConfiguration, TieredQuantityConfiguration, EmailTargetableConfiguration, BenefitFeature, \
LogoPlacement, EmailTargetable, TieredQuantity, RequiredImgAsset, RequiredImgAssetConfiguration, \
RequiredTextAssetConfiguration, RequiredTextAsset
RequiredTextAssetConfiguration, RequiredTextAsset, ProvidedTextAssetConfiguration, ProvidedTextAsset, \
ProvidedFileAssetConfiguration, ProvidedFileAsset
from .sponsorship import Sponsorship, SponsorshipProgram, SponsorshipBenefit, Sponsorship, SponsorshipPackage
from .contract import LegalClause, Contract, signed_contract_random_path
23 changes: 23 additions & 0 deletions sponsors/models/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,26 @@ def value(self):
@value.setter
def value(self, value):
self.text = value


class FileAsset(GenericAsset):
file = models.FileField(
upload_to=generic_asset_path,
blank=False,
null=True,
)

def __str__(self):
return f"File asset: {self.internal_name}"

class Meta:
verbose_name = "File Asset"
verbose_name_plural = "File Assets"

@property
def value(self):
return self.file

@value.setter
def value(self, value):
self.file = value
Loading