fix(MR-16): Use cache for FileField and ImageField (#17)
* Remove casting to list in _get_form_data * Use cache for most fields and admin form for m2m files * MR comments/clean up * Cache should obey exclude and fields * Some more tests and docs * Only use cache for image files * Even more tests and handle save as new * fix test * More tests * minor refactor * Improve test coverage * Add no cover for some places * V0.2.3.dev7 * Adding tests for fieldsets * Added cache timeout * Added another test for an edge case * Fix issue with ManagementForm tampered with * Update cache to only set when form is_multipart * Even more testing changes * Update based on comments on MR and clean up a bit * make test names better Co-authored-by: Thu Trang Pham <thu@joinmodernhealth.com>
This commit is contained in:
@@ -1,48 +0,0 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from admin_confirm.admin import AdminConfirmMixin, confirm_action
|
||||
|
||||
from .models import Item, Inventory, Shop, ShoppingMall
|
||||
|
||||
|
||||
class ItemAdmin(AdminConfirmMixin, admin.ModelAdmin):
|
||||
list_display = ("name", "price", "currency")
|
||||
confirm_change = True
|
||||
|
||||
|
||||
class InventoryAdmin(AdminConfirmMixin, admin.ModelAdmin):
|
||||
list_display = ("shop", "item", "quantity")
|
||||
confirm_change = True
|
||||
confirm_add = True
|
||||
confirmation_fields = ["quantity"]
|
||||
|
||||
|
||||
class ShopAdmin(AdminConfirmMixin, admin.ModelAdmin):
|
||||
confirmation_fields = ["name"]
|
||||
actions = ["show_message", "show_message_no_confirmation"]
|
||||
|
||||
@confirm_action
|
||||
def show_message(modeladmin, request, queryset):
|
||||
shops = ", ".join(shop.name for shop in queryset)
|
||||
modeladmin.message_user(request, f"You selected with confirmation: {shops}")
|
||||
|
||||
show_message.allowed_permissions = ("delete",)
|
||||
|
||||
def show_message_no_confirmation(modeladmin, request, queryset):
|
||||
shops = ", ".join(shop.name for shop in queryset)
|
||||
modeladmin.message_user(request, f"You selected without confirmation: {shops}")
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return request.user.is_superuser
|
||||
|
||||
|
||||
class ShoppingMallAdmin(AdminConfirmMixin, admin.ModelAdmin):
|
||||
confirm_add = True
|
||||
confirm_change = True
|
||||
confirmation_fields = ["name"]
|
||||
|
||||
|
||||
admin.site.register(Item, ItemAdmin)
|
||||
admin.site.register(Inventory, InventoryAdmin)
|
||||
admin.site.register(Shop, ShopAdmin)
|
||||
admin.site.register(ShoppingMall, ShoppingMallAdmin)
|
||||
@@ -0,0 +1,15 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from ..models import GeneralManager, Item, Inventory, Shop, ShoppingMall
|
||||
|
||||
from .item_admin import ItemAdmin
|
||||
from .inventory_admin import InventoryAdmin
|
||||
from .shop_admin import ShopAdmin
|
||||
from .shoppingmall_admin import ShoppingMallAdmin
|
||||
from .generalmanager_admin import GeneralManagerAdmin
|
||||
|
||||
admin.site.register(Item, ItemAdmin)
|
||||
admin.site.register(Inventory, InventoryAdmin)
|
||||
admin.site.register(Shop, ShopAdmin)
|
||||
admin.site.register(ShoppingMall, ShoppingMallAdmin)
|
||||
admin.site.register(GeneralManager, GeneralManagerAdmin)
|
||||
@@ -0,0 +1,5 @@
|
||||
from django.contrib.admin import ModelAdmin
|
||||
|
||||
|
||||
class GeneralManagerAdmin(ModelAdmin):
|
||||
save_as = True
|
||||
@@ -0,0 +1,10 @@
|
||||
from django.contrib.admin import ModelAdmin
|
||||
from admin_confirm.admin import AdminConfirmMixin
|
||||
|
||||
|
||||
class InventoryAdmin(AdminConfirmMixin, ModelAdmin):
|
||||
list_display = ("shop", "item", "quantity")
|
||||
|
||||
confirm_change = True
|
||||
confirm_add = True
|
||||
confirmation_fields = ["quantity"]
|
||||
@@ -0,0 +1,28 @@
|
||||
from django.contrib.admin import ModelAdmin
|
||||
from django.utils.safestring import mark_safe
|
||||
from admin_confirm.admin import AdminConfirmMixin
|
||||
|
||||
|
||||
class ItemAdmin(AdminConfirmMixin, ModelAdmin):
|
||||
confirm_change = True
|
||||
confirm_add = True
|
||||
confirmation_fields = ["price"]
|
||||
|
||||
list_display = ("name", "price", "currency")
|
||||
readonly_fields = ["image_preview"]
|
||||
|
||||
save_as = True
|
||||
save_as_continue = False
|
||||
|
||||
def image_preview(self, obj):
|
||||
if obj.image:
|
||||
return mark_safe('<img src="{obj.image.url}" />')
|
||||
|
||||
# def one(self, obj):
|
||||
# return "Read Only"
|
||||
|
||||
# def two(self, obj):
|
||||
# return "Read Only"
|
||||
|
||||
# def three(self, obj):
|
||||
# return "Read Only"
|
||||
@@ -0,0 +1,21 @@
|
||||
from django.contrib.admin import ModelAdmin
|
||||
from admin_confirm.admin import AdminConfirmMixin, confirm_action
|
||||
|
||||
|
||||
class ShopAdmin(AdminConfirmMixin, ModelAdmin):
|
||||
confirmation_fields = ["name"]
|
||||
actions = ["show_message", "show_message_no_confirmation"]
|
||||
|
||||
@confirm_action
|
||||
def show_message(modeladmin, request, queryset):
|
||||
shops = ", ".join(shop.name for shop in queryset)
|
||||
modeladmin.message_user(request, f"You selected with confirmation: {shops}")
|
||||
|
||||
show_message.allowed_permissions = ("delete",)
|
||||
|
||||
def show_message_no_confirmation(modeladmin, request, queryset):
|
||||
shops = ", ".join(shop.name for shop in queryset)
|
||||
modeladmin.message_user(request, f"You selected without confirmation: {shops}")
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return request.user.is_superuser
|
||||
@@ -0,0 +1,16 @@
|
||||
from ..models import ShoppingMall
|
||||
from django.contrib.admin import ModelAdmin
|
||||
from django.contrib.admin.options import StackedInline
|
||||
from admin_confirm.admin import AdminConfirmMixin
|
||||
|
||||
|
||||
class ShopInline(StackedInline):
|
||||
model = ShoppingMall.shops.through
|
||||
|
||||
|
||||
class ShoppingMallAdmin(AdminConfirmMixin, ModelAdmin):
|
||||
confirm_add = True
|
||||
confirm_change = True
|
||||
confirmation_fields = ["name"]
|
||||
|
||||
inlines = [ShopInline]
|
||||
@@ -0,0 +1,48 @@
|
||||
# Generated by Django 3.1.6 on 2021-02-22 03:12
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('market', '0005_shoppingmall'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='GeneralManager',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=120)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Town',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=120)),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='item',
|
||||
name='file',
|
||||
field=models.FileField(blank=True, null=True, upload_to='tmp/files'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='item',
|
||||
name='image',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='tmp/items'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shoppingmall',
|
||||
name='general_manager',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='market.generalmanager'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shoppingmall',
|
||||
name='town',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='market.town'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.1.6 on 2021-02-24 01:21
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('market', '0006_auto_20210222_0312'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='generalmanager',
|
||||
name='headshot',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='tmp/gm/headshots'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.1.6 on 2021-02-24 08:17
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('market', '0007_generalmanager_headshot'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='item',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
+17
-1
@@ -9,6 +9,9 @@ class Item(models.Model):
|
||||
name = models.CharField(max_length=120)
|
||||
price = models.DecimalField(max_digits=5, decimal_places=2)
|
||||
currency = models.CharField(max_length=3, choices=VALID_CURRENCIES)
|
||||
image = models.ImageField(upload_to="tmp/items", null=True, blank=True)
|
||||
file = models.FileField(upload_to="tmp/files", null=True, blank=True)
|
||||
description = models.TextField(null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -18,7 +21,7 @@ class Shop(models.Model):
|
||||
name = models.CharField(max_length=120)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return str(self.name)
|
||||
|
||||
|
||||
class Inventory(models.Model):
|
||||
@@ -35,9 +38,22 @@ class Inventory(models.Model):
|
||||
notes = models.TextField(default="This is the default", null=True, blank=True)
|
||||
|
||||
|
||||
class GeneralManager(models.Model):
|
||||
name = models.CharField(max_length=120)
|
||||
headshot = models.ImageField(upload_to="tmp/gm/headshots", null=True, blank=True)
|
||||
|
||||
|
||||
class Town(models.Model):
|
||||
name = models.CharField(max_length=120)
|
||||
|
||||
|
||||
class ShoppingMall(models.Model):
|
||||
name = models.CharField(max_length=120)
|
||||
shops = models.ManyToManyField(Shop)
|
||||
general_manager = models.OneToOneField(
|
||||
GeneralManager, on_delete=models.CASCADE, null=True, blank=True
|
||||
)
|
||||
town = models.ForeignKey(Town, on_delete=models.CASCADE, null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
Reference in New Issue
Block a user