kopia lustrzana https://github.com/wagtail/wagtail
Make image upload forms use the correct widget for custom tag models
rodzic
f57fc32ed0
commit
246a270f10
|
@ -4,12 +4,12 @@ from django.forms.models import modelform_factory
|
|||
from django.utils.text import capfirst
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from wagtail.admin import widgets
|
||||
from wagtail.admin.forms.collections import (
|
||||
BaseCollectionMemberForm,
|
||||
CollectionChoiceField,
|
||||
collection_member_permission_formset_factory,
|
||||
)
|
||||
from wagtail.admin.widgets import AdminTagWidget
|
||||
from wagtail.images.fields import WagtailImageField
|
||||
from wagtail.images.formats import get_image_formats
|
||||
from wagtail.images.models import Image
|
||||
|
@ -42,7 +42,7 @@ class BaseImageForm(BaseCollectionMemberForm):
|
|||
# so that when editing, we don't get the 'currently: ...' banner which is
|
||||
# a bit pointless here
|
||||
widgets = {
|
||||
"tags": widgets.AdminTagWidget,
|
||||
"tags": AdminTagWidget,
|
||||
"file": forms.FileInput(),
|
||||
"focal_point_x": forms.HiddenInput(attrs={"class": "focal_point_x"}),
|
||||
"focal_point_y": forms.HiddenInput(attrs={"class": "focal_point_y"}),
|
||||
|
@ -75,10 +75,23 @@ def get_image_form(model):
|
|||
# and when only one collection exists, it will get hidden anyway.
|
||||
fields = list(fields) + ["collection"]
|
||||
|
||||
BaseForm = get_image_base_form()
|
||||
|
||||
# If the base form specifies the 'tags' widget as a plain unconfigured AdminTagWidget,
|
||||
# substitute one that correctly passes the tag model used on the image model.
|
||||
# (If the widget has been overridden via WAGTAILIMAGES_IMAGE_FORM_BASE, leave it
|
||||
# alone and trust that they know what they're doing)
|
||||
widgets = None
|
||||
if BaseForm._meta.widgets.get("tags") == AdminTagWidget:
|
||||
tag_model = model._meta.get_field("tags").related_model
|
||||
widgets = BaseForm._meta.widgets.copy()
|
||||
widgets["tags"] = AdminTagWidget(tag_model=tag_model)
|
||||
|
||||
return modelform_factory(
|
||||
model,
|
||||
form=get_image_base_form(),
|
||||
form=BaseForm,
|
||||
fields=fields,
|
||||
widgets=widgets,
|
||||
formfield_callback=formfield_for_dbfield,
|
||||
)
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
from django import forms
|
||||
from django.test import TestCase, override_settings
|
||||
from taggit import models as taggit_models
|
||||
|
||||
from wagtail.admin import widgets
|
||||
from wagtail.admin.widgets import AdminDateTimeInput
|
||||
from wagtail.images import models
|
||||
from wagtail.images.forms import BaseImageForm, get_image_base_form, get_image_form
|
||||
from wagtail.test.testapp.media_forms import AlternateImageForm, OverriddenWidget
|
||||
from wagtail.test.testapp.models import CustomRestaurantImage, RestaurantTag
|
||||
|
||||
|
||||
class TestImageFormOverride(TestCase):
|
||||
|
@ -21,9 +23,16 @@ class TestImageFormOverride(TestCase):
|
|||
form_cls = get_image_form(models.Image)
|
||||
form = form_cls()
|
||||
self.assertIsInstance(form.fields["tags"].widget, widgets.AdminTagWidget)
|
||||
self.assertEqual(form.fields["tags"].widget.tag_model, taggit_models.Tag)
|
||||
self.assertIsInstance(form.fields["file"].widget, forms.FileInput)
|
||||
self.assertIsInstance(form.fields["focal_point_x"].widget, forms.HiddenInput)
|
||||
|
||||
def test_tags_widget_with_custom_tag_model(self):
|
||||
form_cls = get_image_form(CustomRestaurantImage)
|
||||
form = form_cls()
|
||||
self.assertIsInstance(form.fields["tags"].widget, widgets.AdminTagWidget)
|
||||
self.assertEqual(form.fields["tags"].widget.tag_model, RestaurantTag)
|
||||
|
||||
@override_settings(
|
||||
WAGTAILIMAGES_IMAGE_FORM_BASE="wagtail.test.testapp.media_forms.AlternateImageForm"
|
||||
)
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
# Generated by Django 3.2.11 on 2022-01-27 16:23
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import taggit.managers
|
||||
import wagtail.core.models.collections
|
||||
import wagtail.images.models
|
||||
import wagtail.search.index
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("wagtailcore", "0066_collection_management_permissions"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
("tests", "0064_tagged_restaurant_document"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="CustomRestaurantImage",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("title", models.CharField(max_length=255, verbose_name="title")),
|
||||
(
|
||||
"file",
|
||||
models.ImageField(
|
||||
height_field="height",
|
||||
upload_to=wagtail.images.models.get_upload_to,
|
||||
verbose_name="file",
|
||||
width_field="width",
|
||||
),
|
||||
),
|
||||
("width", models.IntegerField(editable=False, verbose_name="width")),
|
||||
("height", models.IntegerField(editable=False, verbose_name="height")),
|
||||
(
|
||||
"created_at",
|
||||
models.DateTimeField(
|
||||
auto_now_add=True, db_index=True, verbose_name="created at"
|
||||
),
|
||||
),
|
||||
("focal_point_x", models.PositiveIntegerField(blank=True, null=True)),
|
||||
("focal_point_y", models.PositiveIntegerField(blank=True, null=True)),
|
||||
(
|
||||
"focal_point_width",
|
||||
models.PositiveIntegerField(blank=True, null=True),
|
||||
),
|
||||
(
|
||||
"focal_point_height",
|
||||
models.PositiveIntegerField(blank=True, null=True),
|
||||
),
|
||||
("file_size", models.PositiveIntegerField(editable=False, null=True)),
|
||||
(
|
||||
"file_hash",
|
||||
models.CharField(blank=True, editable=False, max_length=40),
|
||||
),
|
||||
(
|
||||
"collection",
|
||||
models.ForeignKey(
|
||||
default=wagtail.core.models.collections.get_root_collection_id,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="+",
|
||||
to="wagtailcore.collection",
|
||||
verbose_name="collection",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
bases=(
|
||||
wagtail.images.models.ImageFileMixin,
|
||||
wagtail.search.index.Indexed,
|
||||
models.Model,
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="TaggedRestaurantImage",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"content_object",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="tagged_items",
|
||||
to="tests.customrestaurantimage",
|
||||
),
|
||||
),
|
||||
(
|
||||
"tag",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="tagged_images",
|
||||
to="tests.restauranttag",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="customrestaurantimage",
|
||||
name="tags",
|
||||
field=taggit.managers.TaggableManager(
|
||||
blank=True,
|
||||
help_text=None,
|
||||
through="tests.TaggedRestaurantImage",
|
||||
to="tests.RestaurantTag",
|
||||
verbose_name="tags",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="customrestaurantimage",
|
||||
name="uploaded_by_user",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
editable=False,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="uploaded by user",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -1734,3 +1734,22 @@ class CustomRestaurantDocument(AbstractDocument):
|
|||
through=TaggedRestaurantDocument,
|
||||
)
|
||||
admin_form_fields = Document.admin_form_fields
|
||||
|
||||
|
||||
# Custom image model with a custom tag field
|
||||
class TaggedRestaurantImage(ItemBase):
|
||||
tag = models.ForeignKey(
|
||||
RestaurantTag, related_name="tagged_images", on_delete=models.CASCADE
|
||||
)
|
||||
content_object = models.ForeignKey(
|
||||
to="tests.CustomRestaurantImage",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="tagged_items",
|
||||
)
|
||||
|
||||
|
||||
class CustomRestaurantImage(AbstractImage):
|
||||
tags = TaggableManager(
|
||||
help_text=None, blank=True, verbose_name="tags", through=TaggedRestaurantImage
|
||||
)
|
||||
admin_form_fields = Image.admin_form_fields
|
||||
|
|
Ładowanie…
Reference in New Issue