mirror of
https://github.com/django-polymorphic/django-polymorphic.git
synced 2026-02-14 02:30:23 +03:00
isort and black with longer line length
This commit is contained in:
parent
8a5b55538d
commit
5b9acd1848
|
|
@ -1,11 +1,10 @@
|
|||
from django.urls import include, path
|
||||
from django.contrib import admin
|
||||
from django.urls import reverse_lazy
|
||||
from django.urls import include, path, reverse_lazy
|
||||
from django.views.generic import RedirectView
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('', RedirectView.as_view(url=reverse_lazy("admin:index"), permanent=False)),
|
||||
path("admin/", admin.site.urls),
|
||||
path("", RedirectView.as_view(url=reverse_lazy("admin:index"), permanent=False)),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from pexp.models import *
|
||||
|
||||
from polymorphic.admin import (
|
||||
PolymorphicChildModelAdmin,
|
||||
PolymorphicChildModelFilter,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ from random import Random
|
|||
|
||||
from django.core.management import BaseCommand
|
||||
from django.db import connection
|
||||
|
||||
from pexp.models import *
|
||||
|
||||
rnd = Random()
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ This module is a scratchpad for general development, testing & debugging.
|
|||
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from django.db import connection
|
||||
|
||||
from pexp.models import *
|
||||
|
||||
|
||||
|
|
@ -19,9 +18,7 @@ class Command(NoArgsCommand):
|
|||
Project.objects.all().delete()
|
||||
a = Project.objects.create(topic="John's gathering")
|
||||
b = ArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")
|
||||
c = ResearchProject.objects.create(
|
||||
topic="Swallow Aerodynamics", supervisor="Dr. Winter"
|
||||
)
|
||||
c = ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
|
||||
print(Project.objects.all())
|
||||
print("")
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ from pprint import pprint
|
|||
|
||||
from django.core.management import BaseCommand
|
||||
from django.db import connection
|
||||
|
||||
from pexp.models import *
|
||||
|
||||
num_objects = 1000
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ This module is a scratchpad for general development, testing & debugging
|
|||
"""
|
||||
|
||||
from django.core.management import BaseCommand
|
||||
|
||||
from pexp.models import *
|
||||
|
||||
|
||||
|
|
@ -14,7 +13,5 @@ class Command(BaseCommand):
|
|||
Project.objects.all().delete()
|
||||
o = Project.objects.create(topic="John's gathering")
|
||||
o = ArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")
|
||||
o = ResearchProject.objects.create(
|
||||
topic="Swallow Aerodynamics", supervisor="Dr. Winter"
|
||||
)
|
||||
o = ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
|
||||
print(Project.objects.all())
|
||||
|
|
|
|||
|
|
@ -263,9 +263,7 @@ class Migration(migrations.Migration):
|
|||
("field3", models.CharField(max_length=10)),
|
||||
(
|
||||
"field4",
|
||||
models.ManyToManyField(
|
||||
related_name="related_c", to="pexp.TestModelB"
|
||||
),
|
||||
models.ManyToManyField(related_name="related_c", to="pexp.TestModelB"),
|
||||
),
|
||||
],
|
||||
options={"abstract": False},
|
||||
|
|
|
|||
|
|
@ -47,9 +47,7 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
|
|||
show_in_index = False
|
||||
|
||||
def __init__(self, model, admin_site, *args, **kwargs):
|
||||
super().__init__(
|
||||
model, admin_site, *args, **kwargs
|
||||
)
|
||||
super().__init__(model, admin_site, *args, **kwargs)
|
||||
|
||||
if self.base_model is None:
|
||||
self.base_model = get_base_polymorphic_model(model)
|
||||
|
|
@ -94,8 +92,7 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
|
|||
f"admin/{app_label}/{opts.object_name.lower()}/change_form.html",
|
||||
"admin/%s/change_form.html" % app_label,
|
||||
# Added:
|
||||
"admin/%s/%s/change_form.html"
|
||||
% (base_app_label, base_opts.object_name.lower()),
|
||||
"admin/%s/%s/change_form.html" % (base_app_label, base_opts.object_name.lower()),
|
||||
"admin/%s/change_form.html" % base_app_label,
|
||||
"admin/polymorphic/change_form.html",
|
||||
"admin/change_form.html",
|
||||
|
|
@ -111,8 +108,7 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
|
|||
base_app_label = base_opts.app_label
|
||||
|
||||
return [
|
||||
"admin/%s/%s/delete_confirmation.html"
|
||||
% (app_label, opts.object_name.lower()),
|
||||
"admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()),
|
||||
"admin/%s/delete_confirmation.html" % app_label,
|
||||
# Added:
|
||||
"admin/%s/%s/delete_confirmation.html"
|
||||
|
|
@ -135,8 +131,7 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
|
|||
f"admin/{app_label}/{opts.object_name.lower()}/object_history.html",
|
||||
"admin/%s/object_history.html" % app_label,
|
||||
# Added:
|
||||
"admin/%s/%s/object_history.html"
|
||||
% (base_app_label, base_opts.object_name.lower()),
|
||||
"admin/%s/%s/object_history.html" % (base_app_label, base_opts.object_name.lower()),
|
||||
"admin/%s/object_history.html" % base_app_label,
|
||||
"admin/polymorphic/object_history.html",
|
||||
"admin/object_history.html",
|
||||
|
|
@ -176,9 +171,7 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
|
|||
def response_post_save_change(self, request, obj):
|
||||
return self._get_parent_admin().response_post_save_change(request, obj)
|
||||
|
||||
def render_change_form(
|
||||
self, request, context, add=False, change=False, form_url="", obj=None
|
||||
):
|
||||
def render_change_form(self, request, context, add=False, change=False, form_url="", obj=None):
|
||||
context.update({"base_opts": self.base_model._meta})
|
||||
return super().render_change_form(
|
||||
request, context, add=add, change=change, form_url=form_url, obj=obj
|
||||
|
|
@ -186,18 +179,14 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
|
|||
|
||||
def delete_view(self, request, object_id, context=None):
|
||||
extra_context = {"base_opts": self.base_model._meta}
|
||||
return super().delete_view(
|
||||
request, object_id, extra_context
|
||||
)
|
||||
return super().delete_view(request, object_id, extra_context)
|
||||
|
||||
def history_view(self, request, object_id, extra_context=None):
|
||||
# Make sure the history view can also display polymorphic breadcrumbs
|
||||
context = {"base_opts": self.base_model._meta}
|
||||
if extra_context:
|
||||
context.update(extra_context)
|
||||
return super().history_view(
|
||||
request, object_id, extra_context=context
|
||||
)
|
||||
return super().history_view(request, object_id, extra_context=context)
|
||||
|
||||
# ---- Extra: improving the form/fieldset default display ----
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@ class PolymorphicChildModelFilter(admin.SimpleListFilter):
|
|||
if choice_value == value:
|
||||
return queryset.filter(polymorphic_ctype_id=choice_value)
|
||||
raise PermissionDenied(
|
||||
'Invalid ContentType "{}". It must be registered as child model.'.format(
|
||||
value
|
||||
)
|
||||
'Invalid ContentType "{}". It must be registered as child model.'.format(value)
|
||||
)
|
||||
return queryset
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@ from polymorphic.formsets import (
|
|||
from .inlines import PolymorphicInlineModelAdmin
|
||||
|
||||
|
||||
class GenericPolymorphicInlineModelAdmin(
|
||||
PolymorphicInlineModelAdmin, GenericInlineModelAdmin
|
||||
):
|
||||
class GenericPolymorphicInlineModelAdmin(PolymorphicInlineModelAdmin, GenericInlineModelAdmin):
|
||||
"""
|
||||
Base class for variation of inlines based on generic foreign keys.
|
||||
"""
|
||||
|
|
@ -51,18 +49,16 @@ class GenericPolymorphicInlineModelAdmin(
|
|||
Expose the ContentType that the child relates to.
|
||||
This can be used for the ``polymorphic_ctype`` field.
|
||||
"""
|
||||
return ContentType.objects.get_for_model(
|
||||
self.model, for_concrete_model=False
|
||||
)
|
||||
return ContentType.objects.get_for_model(self.model, for_concrete_model=False)
|
||||
|
||||
def get_formset_child(self, request, obj=None, **kwargs):
|
||||
# Similar to GenericInlineModelAdmin.get_formset(),
|
||||
# make sure the GFK is automatically excluded from the form
|
||||
defaults = {"ct_field": self.ct_field, "fk_field": self.ct_fk_field}
|
||||
defaults.update(kwargs)
|
||||
return super(
|
||||
GenericPolymorphicInlineModelAdmin.Child, self
|
||||
).get_formset_child(request, obj=obj, **defaults)
|
||||
return super(GenericPolymorphicInlineModelAdmin.Child, self).get_formset_child(
|
||||
request, obj=obj, **defaults
|
||||
)
|
||||
|
||||
|
||||
class GenericStackedPolymorphicInline(GenericPolymorphicInlineModelAdmin):
|
||||
|
|
|
|||
|
|
@ -41,9 +41,7 @@ class PolymorphicInlineAdminFormSet(InlineAdminFormSet):
|
|||
"""
|
||||
Output all forms using the proper subtype settings.
|
||||
"""
|
||||
for form, original in zip(
|
||||
self.formset.initial_forms, self.formset.get_queryset()
|
||||
):
|
||||
for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()):
|
||||
# Output the form
|
||||
model = original.get_real_instance_class()
|
||||
child_inline = self.opts.get_child_inline_instance(model)
|
||||
|
|
@ -124,15 +122,15 @@ class PolymorphicInlineSupportMixin:
|
|||
:class:`~django.contrib.admin.helpers.InlineAdminFormSet` for the polymorphic formsets.
|
||||
"""
|
||||
|
||||
def get_inline_formsets(
|
||||
self, request, formsets, inline_instances, obj=None, *args, **kwargs
|
||||
):
|
||||
def get_inline_formsets(self, request, formsets, inline_instances, obj=None, *args, **kwargs):
|
||||
"""
|
||||
Overwritten version to produce the proper admin wrapping for the
|
||||
polymorphic inline formset. This fixes the media and form appearance
|
||||
of the inline polymorphic models.
|
||||
"""
|
||||
inline_admin_formsets = super().get_inline_formsets(request, formsets, inline_instances, obj=obj)
|
||||
inline_admin_formsets = super().get_inline_formsets(
|
||||
request, formsets, inline_instances, obj=obj
|
||||
)
|
||||
|
||||
for admin_formset in inline_admin_formsets:
|
||||
if isinstance(admin_formset.formset, BasePolymorphicModelFormSet):
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@ class PolymorphicInlineModelAdmin(InlineModelAdmin):
|
|||
#: This can be redefined for subclasses.
|
||||
polymorphic_media = Media(
|
||||
js=(
|
||||
"admin/js/vendor/jquery/jquery{}.js".format(
|
||||
"" if settings.DEBUG else ".min"
|
||||
),
|
||||
"admin/js/vendor/jquery/jquery{}.js".format("" if settings.DEBUG else ".min"),
|
||||
"admin/js/jquery.init.js",
|
||||
"polymorphic/js/polymorphic_inlines.js",
|
||||
),
|
||||
|
|
@ -96,9 +94,7 @@ class PolymorphicInlineModelAdmin(InlineModelAdmin):
|
|||
try:
|
||||
return self._child_inlines_lookup[model]
|
||||
except KeyError:
|
||||
raise UnsupportedChildType(
|
||||
f"Model '{model.__name__}' not found in child_inlines"
|
||||
)
|
||||
raise UnsupportedChildType(f"Model '{model.__name__}' not found in child_inlines")
|
||||
|
||||
def get_formset(self, request, obj=None, **kwargs):
|
||||
"""
|
||||
|
|
@ -109,9 +105,7 @@ class PolymorphicInlineModelAdmin(InlineModelAdmin):
|
|||
:rtype: type
|
||||
"""
|
||||
# Construct the FormSet class
|
||||
FormSet = super().get_formset(
|
||||
request, obj=obj, **kwargs
|
||||
)
|
||||
FormSet = super().get_formset(request, obj=obj, **kwargs)
|
||||
|
||||
# Instead of completely redefining super().get_formset(), we use
|
||||
# the regular inlineformset_factory(), and amend that with our extra bits.
|
||||
|
|
@ -161,10 +155,7 @@ class PolymorphicInlineModelAdmin(InlineModelAdmin):
|
|||
child_media = child_instance.media
|
||||
|
||||
# Avoid adding the same media object again and again
|
||||
if (
|
||||
child_media._css != base_media._css
|
||||
and child_media._js != base_media._js
|
||||
):
|
||||
if child_media._css != base_media._css and child_media._js != base_media._js:
|
||||
add_media(all_media, child_media)
|
||||
|
||||
add_media(all_media, self.polymorphic_media)
|
||||
|
|
@ -239,11 +230,7 @@ class PolymorphicInlineModelAdmin(InlineModelAdmin):
|
|||
# Add forcefully, as Django 1.10 doesn't include readonly fields.
|
||||
exclude.append("polymorphic_ctype")
|
||||
|
||||
if (
|
||||
self.exclude is None
|
||||
and hasattr(self.form, "_meta")
|
||||
and self.form._meta.exclude
|
||||
):
|
||||
if self.exclude is None and hasattr(self.form, "_meta") and self.form._meta.exclude:
|
||||
# Take the custom ModelForm's Meta.exclude into account only if the
|
||||
# InlineModelAdmin doesn't define its own.
|
||||
exclude.extend(self.form._meta.exclude)
|
||||
|
|
@ -253,9 +240,7 @@ class PolymorphicInlineModelAdmin(InlineModelAdmin):
|
|||
"form": self.form,
|
||||
"fields": fields,
|
||||
"exclude": exclude or None,
|
||||
"formfield_callback": partial(
|
||||
self.formfield_for_dbfield, request=request
|
||||
),
|
||||
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -62,9 +62,7 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
pk_regex = r"(\d+|__fk__)"
|
||||
|
||||
def __init__(self, model, admin_site, *args, **kwargs):
|
||||
super().__init__(
|
||||
model, admin_site, *args, **kwargs
|
||||
)
|
||||
super().__init__(model, admin_site, *args, **kwargs)
|
||||
self._is_setup = False
|
||||
|
||||
if self.base_model is None:
|
||||
|
|
@ -96,15 +94,11 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
# After the get_urls() is called, the URLs of the child model can't be exposed anymore to the Django URLconf,
|
||||
# which also means that a "Save and continue editing" button won't work.
|
||||
if self._is_setup:
|
||||
raise RegistrationClosed(
|
||||
"The admin model can't be registered anymore at this point."
|
||||
)
|
||||
raise RegistrationClosed("The admin model can't be registered anymore at this point.")
|
||||
|
||||
if not issubclass(model, self.base_model):
|
||||
raise TypeError(
|
||||
"{} should be a subclass of {}".format(
|
||||
model.__name__, self.base_model.__name__
|
||||
)
|
||||
"{} should be a subclass of {}".format(model.__name__, self.base_model.__name__)
|
||||
)
|
||||
if not issubclass(model_admin, admin.ModelAdmin):
|
||||
raise TypeError(
|
||||
|
|
@ -134,7 +128,9 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
"""
|
||||
self._lazy_setup()
|
||||
choices = []
|
||||
content_types = ContentType.objects.get_for_models(*self.get_child_models(), for_concrete_models=False)
|
||||
content_types = ContentType.objects.get_for_models(
|
||||
*self.get_child_models(), for_concrete_models=False
|
||||
)
|
||||
|
||||
for model, ct in content_types.items():
|
||||
perm_function_name = f"has_{action}_permission"
|
||||
|
|
@ -148,15 +144,11 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
def _get_real_admin(self, object_id, super_if_self=True):
|
||||
try:
|
||||
obj = (
|
||||
self.model.objects.non_polymorphic()
|
||||
.values("polymorphic_ctype")
|
||||
.get(pk=object_id)
|
||||
self.model.objects.non_polymorphic().values("polymorphic_ctype").get(pk=object_id)
|
||||
)
|
||||
except self.model.DoesNotExist:
|
||||
raise Http404
|
||||
return self._get_real_admin_by_ct(
|
||||
obj["polymorphic_ctype"], super_if_self=super_if_self
|
||||
)
|
||||
return self._get_real_admin_by_ct(obj["polymorphic_ctype"], super_if_self=super_if_self)
|
||||
|
||||
def _get_real_admin_by_ct(self, ct_id, super_if_self=True):
|
||||
try:
|
||||
|
|
@ -176,9 +168,7 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
# Hence, make sure this is a derived object, or risk exposing other admin interfaces.
|
||||
if model_class not in self._child_models:
|
||||
raise PermissionDenied(
|
||||
"Invalid model '{}', it must be registered as child model.".format(
|
||||
model_class
|
||||
)
|
||||
"Invalid model '{}', it must be registered as child model.".format(model_class)
|
||||
)
|
||||
|
||||
try:
|
||||
|
|
@ -187,9 +177,7 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
real_admin = self._child_admin_site._registry[model_class]
|
||||
except KeyError:
|
||||
raise ChildAdminNotRegistered(
|
||||
"No child admin site was registered for a '{}' model.".format(
|
||||
model_class
|
||||
)
|
||||
"No child admin site was registered for a '{}' model.".format(model_class)
|
||||
)
|
||||
|
||||
if super_if_self and real_admin is self:
|
||||
|
|
@ -236,9 +224,7 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
return real_admin.changeform_view(request, object_id, *args, **kwargs)
|
||||
else:
|
||||
# Add view. As it should already be handled via `add_view`, this means something custom is done here!
|
||||
return super().changeform_view(
|
||||
request, object_id, *args, **kwargs
|
||||
)
|
||||
return super().changeform_view(request, object_id, *args, **kwargs)
|
||||
|
||||
def history_view(self, request, object_id, extra_context=None):
|
||||
"""Redirect the history view to the real admin."""
|
||||
|
|
@ -287,14 +273,12 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
object_id = int(path[0:pos])
|
||||
except ValueError:
|
||||
raise Http404(
|
||||
"No ct_id parameter, unable to find admin subclass for path '{}'.".format(
|
||||
path
|
||||
)
|
||||
"No ct_id parameter, unable to find admin subclass for path '{}'.".format(path)
|
||||
)
|
||||
|
||||
ct_id = self.model.objects.values_list(
|
||||
"polymorphic_ctype_id", flat=True
|
||||
).get(pk=object_id)
|
||||
ct_id = self.model.objects.values_list("polymorphic_ctype_id", flat=True).get(
|
||||
pk=object_id
|
||||
)
|
||||
|
||||
real_admin = self._get_real_admin_by_ct(ct_id)
|
||||
resolver = URLResolver("^", real_admin.urls)
|
||||
|
|
@ -331,9 +315,7 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
form.fields["ct_id"].choices = choices
|
||||
|
||||
if form.is_valid():
|
||||
return HttpResponseRedirect(
|
||||
"?ct_id={}{}".format(form.cleaned_data["ct_id"], extra_qs)
|
||||
)
|
||||
return HttpResponseRedirect("?ct_id={}{}".format(form.cleaned_data["ct_id"], extra_qs))
|
||||
|
||||
# Wrap in all admin layout
|
||||
fieldsets = ((None, {"fields": ("ct_id",)}),)
|
||||
|
|
@ -390,8 +372,7 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
|
|||
f"admin/{app_label}/{opts.object_name.lower()}/change_list.html",
|
||||
"admin/%s/change_list.html" % app_label,
|
||||
# Added base class:
|
||||
"admin/%s/%s/change_list.html"
|
||||
% (base_app_label, base_opts.object_name.lower()),
|
||||
"admin/%s/%s/change_list.html" % (base_app_label, base_opts.object_name.lower()),
|
||||
"admin/%s/change_list.html" % base_app_label,
|
||||
"admin/change_list.html",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -19,9 +19,7 @@ from .query import PolymorphicQuerySet
|
|||
# These are forbidden as field names (a descriptive exception is raised)
|
||||
POLYMORPHIC_SPECIAL_Q_KWORDS = ["instance_of", "not_instance_of"]
|
||||
|
||||
DUMPDATA_COMMAND = os.path.join(
|
||||
"django", "core", "management", "commands", "dumpdata.py"
|
||||
)
|
||||
DUMPDATA_COMMAND = os.path.join("django", "core", "management", "commands", "dumpdata.py")
|
||||
|
||||
|
||||
class ManagerInheritanceWarning(RuntimeWarning):
|
||||
|
|
@ -61,9 +59,7 @@ class PolymorphicModelBase(ModelBase):
|
|||
|
||||
# Workaround compatibility issue with six.with_metaclass() and custom Django model metaclasses:
|
||||
if not attrs and model_name == "NewBase":
|
||||
return super().__new__(
|
||||
self, model_name, bases, attrs, **kwargs
|
||||
)
|
||||
return super().__new__(self, model_name, bases, attrs, **kwargs)
|
||||
|
||||
# Make sure that manager_inheritance_from_future is set, since django-polymorphic 1.x already
|
||||
# simulated that behavior on the polymorphic manager to all subclasses behave like polymorphics
|
||||
|
|
@ -72,9 +68,7 @@ class PolymorphicModelBase(ModelBase):
|
|||
if not hasattr(attrs["Meta"], "manager_inheritance_from_future"):
|
||||
attrs["Meta"].manager_inheritance_from_future = True
|
||||
else:
|
||||
attrs["Meta"] = type(
|
||||
"Meta", (object,), {"manager_inheritance_from_future": True}
|
||||
)
|
||||
attrs["Meta"] = type("Meta", (object,), {"manager_inheritance_from_future": True})
|
||||
|
||||
# create new model
|
||||
new_class = self.call_superclass_new_method(model_name, bases, attrs, **kwargs)
|
||||
|
|
@ -117,9 +111,7 @@ class PolymorphicModelBase(ModelBase):
|
|||
|
||||
if do_app_label_workaround:
|
||||
meta.app_label = "poly_dummy_app_label"
|
||||
new_class = super().__new__(
|
||||
self, model_name, bases, attrs, **kwargs
|
||||
)
|
||||
new_class = super().__new__(self, model_name, bases, attrs, **kwargs)
|
||||
if do_app_label_workaround:
|
||||
del meta.app_label
|
||||
return new_class
|
||||
|
|
@ -167,9 +159,7 @@ class PolymorphicModelBase(ModelBase):
|
|||
def base_objects(self):
|
||||
warnings.warn(
|
||||
"Using PolymorphicModel.base_objects is deprecated.\n"
|
||||
"Use {}.objects.non_polymorphic() instead.".format(
|
||||
self.__class__.__name__
|
||||
),
|
||||
"Use {}.objects.non_polymorphic() instead.".format(self.__class__.__name__),
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
|
@ -198,18 +188,14 @@ class PolymorphicModelBase(ModelBase):
|
|||
# (non-polymorphic default manager is 'base_objects' for polymorphic models).
|
||||
# This way we don't need to patch django.core.management.commands.dumpdata
|
||||
# for all supported Django versions.
|
||||
frm = inspect.stack()[
|
||||
1
|
||||
] # frm[1] is caller file name, frm[3] is caller function name
|
||||
frm = inspect.stack()[1] # frm[1] is caller file name, frm[3] is caller function name
|
||||
if DUMPDATA_COMMAND in frm[1]:
|
||||
return self._base_objects
|
||||
|
||||
manager = super()._default_manager
|
||||
if not isinstance(manager, PolymorphicManager):
|
||||
warnings.warn(
|
||||
"{}._default_manager is not a PolymorphicManager".format(
|
||||
self.__class__.__name__
|
||||
),
|
||||
"{}._default_manager is not a PolymorphicManager".format(self.__class__.__name__),
|
||||
ManagerInheritanceWarning,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Compatibility with Python 2 (taken from 'django.utils.six')"""
|
||||
|
||||
|
||||
def with_metaclass(meta, *bases):
|
||||
class metaclass(type):
|
||||
def __new__(cls, name, this_bases, d):
|
||||
|
|
|
|||
|
|
@ -83,9 +83,7 @@ class PolymorphicFormSetView(PolymorphicFormSetMixin, extra_views.ModelFormSetVi
|
|||
formset_class = BasePolymorphicModelFormSet
|
||||
|
||||
|
||||
class PolymorphicInlineFormSetView(
|
||||
PolymorphicFormSetMixin, extra_views.InlineFormSetView
|
||||
):
|
||||
class PolymorphicInlineFormSetView(PolymorphicFormSetMixin, extra_views.InlineFormSetView):
|
||||
"""
|
||||
A view that displays a single polymorphic formset - with one parent object.
|
||||
This is a variation of the :mod:`extra_views` package classes for django-polymorphic.
|
||||
|
|
@ -107,9 +105,7 @@ class PolymorphicInlineFormSetView(
|
|||
formset_class = BasePolymorphicInlineFormSet
|
||||
|
||||
|
||||
class PolymorphicInlineFormSet(
|
||||
PolymorphicFormSetMixin, extra_views.InlineFormSetFactory
|
||||
):
|
||||
class PolymorphicInlineFormSet(PolymorphicFormSetMixin, extra_views.InlineFormSetFactory):
|
||||
"""
|
||||
An inline to add to the ``inlines`` of
|
||||
the :class:`~extra_views.advanced.CreateWithInlinesView`
|
||||
|
|
|
|||
|
|
@ -42,9 +42,7 @@ class GenericPolymorphicFormSetChild(PolymorphicFormSetChild):
|
|||
not isinstance(ct_field, models.ForeignKey)
|
||||
or ct_field.remote_field.model != ContentType
|
||||
):
|
||||
raise Exception(
|
||||
"fk_name '%s' is not a ForeignKey to ContentType" % ct_field
|
||||
)
|
||||
raise Exception("fk_name '%s' is not a ForeignKey to ContentType" % ct_field)
|
||||
|
||||
fk_field = opts.get_field(self.fk_field) # let the exception propagate
|
||||
exclude.extend([ct_field.name, fk_field.name])
|
||||
|
|
@ -53,9 +51,7 @@ class GenericPolymorphicFormSetChild(PolymorphicFormSetChild):
|
|||
return super().get_form(**kwargs)
|
||||
|
||||
|
||||
class BaseGenericPolymorphicInlineFormSet(
|
||||
BaseGenericInlineFormSet, BasePolymorphicModelFormSet
|
||||
):
|
||||
class BaseGenericPolymorphicInlineFormSet(BaseGenericInlineFormSet, BasePolymorphicModelFormSet):
|
||||
"""
|
||||
Polymorphic formset variation for inline generic formsets
|
||||
"""
|
||||
|
|
@ -130,7 +126,5 @@ def generic_polymorphic_inlineformset_factory(
|
|||
child_kwargs.update(child_form_kwargs)
|
||||
|
||||
FormSet = generic_inlineformset_factory(**kwargs)
|
||||
FormSet.child_forms = polymorphic_child_forms_factory(
|
||||
formset_children, **child_kwargs
|
||||
)
|
||||
FormSet.child_forms = polymorphic_child_forms_factory(formset_children, **child_kwargs)
|
||||
return FormSet
|
||||
|
|
|
|||
|
|
@ -180,9 +180,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
|
|||
if self.is_bound:
|
||||
if "instance" in defaults:
|
||||
# Object is already bound to a model, won't change the content type
|
||||
model = defaults[
|
||||
"instance"
|
||||
].get_real_instance_class() # allow proxy models
|
||||
model = defaults["instance"].get_real_instance_class() # allow proxy models
|
||||
else:
|
||||
# Extra or empty form, use the provided type.
|
||||
# Note this completely tru
|
||||
|
|
@ -191,9 +189,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
|
|||
ct_id = int(self.data[f"{prefix}-polymorphic_ctype"])
|
||||
except (KeyError, ValueError):
|
||||
raise ValidationError(
|
||||
"Formset row {} has no 'polymorphic_ctype' defined!".format(
|
||||
prefix
|
||||
)
|
||||
"Formset row {} has no 'polymorphic_ctype' defined!".format(prefix)
|
||||
)
|
||||
|
||||
model = ContentType.objects.get_for_id(ct_id).model_class()
|
||||
|
|
@ -204,9 +200,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
|
|||
)
|
||||
else:
|
||||
if "instance" in defaults:
|
||||
model = defaults[
|
||||
"instance"
|
||||
].get_real_instance_class() # allow proxy models
|
||||
model = defaults["instance"].get_real_instance_class() # allow proxy models
|
||||
elif "polymorphic_ctype" in defaults.get("initial", {}):
|
||||
model = defaults["initial"]["polymorphic_ctype"].model_class()
|
||||
elif i < len(self.queryset_data):
|
||||
|
|
@ -225,12 +219,14 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
|
|||
|
||||
def add_fields(self, form, index):
|
||||
"""Add a hidden field for the content type."""
|
||||
ct = ContentType.objects.get_for_model(
|
||||
form._meta.model, for_concrete_model=False
|
||||
)
|
||||
ct = ContentType.objects.get_for_model(form._meta.model, for_concrete_model=False)
|
||||
choices = [(ct.pk, ct)] # Single choice, existing forms can't change the value.
|
||||
form.fields["polymorphic_ctype"] = forms.TypedChoiceField(
|
||||
choices=choices, initial=ct.pk, required=False, widget=forms.HiddenInput, coerce=int,
|
||||
choices=choices,
|
||||
initial=ct.pk,
|
||||
required=False,
|
||||
widget=forms.HiddenInput,
|
||||
coerce=int,
|
||||
)
|
||||
super().add_fields(form, index)
|
||||
|
||||
|
|
@ -239,9 +235,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
|
|||
Return the proper form class for the given model.
|
||||
"""
|
||||
if not self.child_forms:
|
||||
raise ImproperlyConfigured(
|
||||
f"No 'child_forms' defined in {self.__class__.__name__}"
|
||||
)
|
||||
raise ImproperlyConfigured(f"No 'child_forms' defined in {self.__class__.__name__}")
|
||||
if not issubclass(model, PolymorphicModel):
|
||||
raise TypeError(f"Expect polymorphic model type, not {model}")
|
||||
|
||||
|
|
@ -286,7 +280,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
|
|||
prefix=self.add_prefix("__prefix__"),
|
||||
empty_permitted=True,
|
||||
use_required_attribute=False,
|
||||
**kwargs
|
||||
**kwargs,
|
||||
)
|
||||
self.add_fields(form, None)
|
||||
forms.append(form)
|
||||
|
|
@ -366,9 +360,7 @@ def polymorphic_modelformset_factory(
|
|||
if child_form_kwargs:
|
||||
child_kwargs.update(child_form_kwargs)
|
||||
|
||||
FormSet.child_forms = polymorphic_child_forms_factory(
|
||||
formset_children, **child_kwargs
|
||||
)
|
||||
FormSet.child_forms = polymorphic_child_forms_factory(formset_children, **child_kwargs)
|
||||
return FormSet
|
||||
|
||||
|
||||
|
|
@ -451,7 +443,5 @@ def polymorphic_inlineformset_factory(
|
|||
if child_form_kwargs:
|
||||
child_kwargs.update(child_form_kwargs)
|
||||
|
||||
FormSet.child_forms = polymorphic_child_forms_factory(
|
||||
formset_children, **child_kwargs
|
||||
)
|
||||
FormSet.child_forms = polymorphic_child_forms_factory(formset_children, **child_kwargs)
|
||||
return FormSet
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@ class PolymorphicManager(models.Manager):
|
|||
|
||||
@classmethod
|
||||
def from_queryset(cls, queryset_class, class_name=None):
|
||||
manager = super().from_queryset(
|
||||
queryset_class, class_name=class_name
|
||||
)
|
||||
manager = super().from_queryset(queryset_class, class_name=class_name)
|
||||
# also set our version, Django uses _queryset_class
|
||||
manager.queryset_class = queryset_class
|
||||
return manager
|
||||
|
|
|
|||
|
|
@ -3,10 +3,7 @@ Seamless Polymorphic Inheritance for Django Models
|
|||
"""
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import models
|
||||
from django.db.models.fields.related import (
|
||||
ForwardManyToOneDescriptor,
|
||||
ReverseOneToOneDescriptor,
|
||||
)
|
||||
from django.db.models.fields.related import ForwardManyToOneDescriptor, ReverseOneToOneDescriptor
|
||||
from django.db.utils import DEFAULT_DB_ALIAS
|
||||
|
||||
from polymorphic.compat import with_metaclass
|
||||
|
|
@ -77,9 +74,9 @@ class PolymorphicModel(with_metaclass(PolymorphicModelBase, models.Model)):
|
|||
# field to figure out the real class of this object
|
||||
# (used by PolymorphicQuerySet._get_real_instances)
|
||||
if not self.polymorphic_ctype_id:
|
||||
self.polymorphic_ctype = ContentType.objects.db_manager(
|
||||
using
|
||||
).get_for_model(self, for_concrete_model=False)
|
||||
self.polymorphic_ctype = ContentType.objects.db_manager(using).get_for_model(
|
||||
self, for_concrete_model=False
|
||||
)
|
||||
|
||||
pre_save_polymorphic.alters_data = True
|
||||
|
||||
|
|
@ -208,9 +205,7 @@ class PolymorphicModel(with_metaclass(PolymorphicModelBase, models.Model)):
|
|||
|
||||
return accessor_function
|
||||
|
||||
subclasses_and_superclasses_accessors = (
|
||||
self._get_inheritance_relation_fields_and_models()
|
||||
)
|
||||
subclasses_and_superclasses_accessors = self._get_inheritance_relation_fields_and_models()
|
||||
|
||||
for name, model in subclasses_and_superclasses_accessors.items():
|
||||
# Here be dragons.
|
||||
|
|
@ -266,9 +261,7 @@ class PolymorphicModel(with_metaclass(PolymorphicModelBase, models.Model)):
|
|||
to_subclass_fieldname = sub_cls.__name__.lower()
|
||||
else:
|
||||
# otherwise use the given related name
|
||||
to_subclass_fieldname = (
|
||||
super_to_sub_related_field.related_name
|
||||
)
|
||||
to_subclass_fieldname = super_to_sub_related_field.related_name
|
||||
|
||||
add_model_if_regular(sub_cls, to_subclass_fieldname, result)
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ class PolymorphicQuerySet(QuerySet):
|
|||
|
||||
# Makes _filter_or_exclude compatible with the change in signature introduced in django at 9c9a3fe
|
||||
if get_django_version() >= "3.2":
|
||||
|
||||
def _filter_or_exclude(self, negate, args, kwargs):
|
||||
# We override this internal Django function as it is used for all filter member functions.
|
||||
q_objects = translate_polymorphic_filter_definitions_in_args(
|
||||
|
|
@ -170,10 +171,10 @@ class PolymorphicQuerySet(QuerySet):
|
|||
queryset_model=self.model, kwargs=kwargs, using=self.db
|
||||
)
|
||||
args = list(q_objects) + additional_args
|
||||
return super()._filter_or_exclude(
|
||||
negate=negate, args=args, kwargs=kwargs
|
||||
)
|
||||
return super()._filter_or_exclude(negate=negate, args=args, kwargs=kwargs)
|
||||
|
||||
else:
|
||||
|
||||
def _filter_or_exclude(self, negate, *args, **kwargs):
|
||||
# We override this internal Django function as it is used for all filter member functions.
|
||||
q_objects = translate_polymorphic_filter_definitions_in_args(
|
||||
|
|
@ -275,12 +276,12 @@ class PolymorphicQuerySet(QuerySet):
|
|||
a.name = translate_polymorphic_field_path(self.model, a.name)
|
||||
|
||||
def test___lookup(a):
|
||||
""" *args might be complex expressions too in django 1.8 so
|
||||
the testing for a '___' is rather complex on this one """
|
||||
"""*args might be complex expressions too in django 1.8 so
|
||||
the testing for a '___' is rather complex on this one"""
|
||||
if isinstance(a, Q):
|
||||
|
||||
def tree_node_test___lookup(my_model, node):
|
||||
" process all children of this Q node "
|
||||
"process all children of this Q node"
|
||||
for i in range(len(node.children)):
|
||||
child = node.children[i]
|
||||
|
||||
|
|
@ -391,9 +392,7 @@ class PolymorphicQuerySet(QuerySet):
|
|||
resultlist.append(base_object)
|
||||
else:
|
||||
real_concrete_class = base_object.get_real_instance_class()
|
||||
real_concrete_class_id = (
|
||||
base_object.get_real_concrete_instance_class_id()
|
||||
)
|
||||
real_concrete_class_id = base_object.get_real_concrete_instance_class_id()
|
||||
|
||||
if real_concrete_class_id is None:
|
||||
# Dealing with a stale content type
|
||||
|
|
@ -407,12 +406,8 @@ class PolymorphicQuerySet(QuerySet):
|
|||
real_concrete_class = content_type_manager.get_for_id(
|
||||
real_concrete_class_id
|
||||
).model_class()
|
||||
idlist_per_model[real_concrete_class].append(
|
||||
getattr(base_object, pk_name)
|
||||
)
|
||||
indexlist_per_model[real_concrete_class].append(
|
||||
(i, len(resultlist))
|
||||
)
|
||||
idlist_per_model[real_concrete_class].append(getattr(base_object, pk_name))
|
||||
indexlist_per_model[real_concrete_class].append((i, len(resultlist)))
|
||||
resultlist.append(None)
|
||||
|
||||
# For each model in "idlist_per_model" request its objects (the real model)
|
||||
|
|
@ -460,8 +455,7 @@ class PolymorphicQuerySet(QuerySet):
|
|||
)
|
||||
|
||||
real_objects_dict = {
|
||||
getattr(real_object, pk_name): real_object
|
||||
for real_object in real_objects
|
||||
getattr(real_object, pk_name): real_object for real_object in real_objects
|
||||
}
|
||||
|
||||
for i, j in indices:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from collections import deque
|
|||
|
||||
from django.apps import apps
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import FieldError, FieldDoesNotExist
|
||||
from django.core.exceptions import FieldDoesNotExist, FieldError
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.db.models.fields.related import ForeignObjectRel, RelatedField
|
||||
|
|
@ -57,11 +57,9 @@ def translate_polymorphic_filter_definitions_in_kwargs(
|
|||
return additional_args
|
||||
|
||||
|
||||
def translate_polymorphic_Q_object(
|
||||
queryset_model, potential_q_object, using=DEFAULT_DB_ALIAS
|
||||
):
|
||||
def translate_polymorphic_Q_object(queryset_model, potential_q_object, using=DEFAULT_DB_ALIAS):
|
||||
def tree_node_correct_field_specs(my_model, node):
|
||||
" process all children of this Q node "
|
||||
"process all children of this Q node"
|
||||
for i in range(len(node.children)):
|
||||
child = node.children[i]
|
||||
|
||||
|
|
@ -83,9 +81,7 @@ def translate_polymorphic_Q_object(
|
|||
return potential_q_object
|
||||
|
||||
|
||||
def translate_polymorphic_filter_definitions_in_args(
|
||||
queryset_model, args, using=DEFAULT_DB_ALIAS
|
||||
):
|
||||
def translate_polymorphic_filter_definitions_in_args(queryset_model, args, using=DEFAULT_DB_ALIAS):
|
||||
"""
|
||||
Translate the non-keyword argument list for PolymorphicQuerySet.filter()
|
||||
|
||||
|
|
@ -97,8 +93,7 @@ def translate_polymorphic_filter_definitions_in_args(
|
|||
Returns: modified Q objects
|
||||
"""
|
||||
return [
|
||||
translate_polymorphic_Q_object(queryset_model, copy.deepcopy(q), using=using)
|
||||
for q in args
|
||||
translate_polymorphic_Q_object(queryset_model, copy.deepcopy(q), using=using) for q in args
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -300,9 +295,7 @@ def create_instanceof_q(modellist, not_instance_of=False, using=DEFAULT_DB_ALIAS
|
|||
def _get_mro_content_type_ids(models, using):
|
||||
contenttype_ids = set()
|
||||
for model in models:
|
||||
ct = ContentType.objects.db_manager(using).get_for_model(
|
||||
model, for_concrete_model=False
|
||||
)
|
||||
ct = ContentType.objects.db_manager(using).get_for_model(model, for_concrete_model=False)
|
||||
contenttype_ids.add(ct.pk)
|
||||
subclasses = model.__subclasses__()
|
||||
if subclasses:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ RE_DEFERRED = re.compile("_Deferred_.*")
|
|||
|
||||
|
||||
class ShowFieldBase:
|
||||
""" base class for the ShowField... model mixins, does the work """
|
||||
"""base class for the ShowField... model mixins, does the work"""
|
||||
|
||||
# cause nicer multiline PolymorphicQuery output
|
||||
polymorphic_query_multiline_output = True
|
||||
|
|
@ -52,10 +52,7 @@ class ShowFieldBase:
|
|||
"helper for __unicode__"
|
||||
done_fields = set()
|
||||
for field in self._meta.fields + self._meta.many_to_many:
|
||||
if (
|
||||
field.name in self.polymorphic_internal_model_fields
|
||||
or "_ptr" in field.name
|
||||
):
|
||||
if field.name in self.polymorphic_internal_model_fields or "_ptr" in field.name:
|
||||
continue
|
||||
if field.name in done_fields:
|
||||
continue # work around django diamond inheritance problem
|
||||
|
|
@ -64,11 +61,7 @@ class ShowFieldBase:
|
|||
out = field.name
|
||||
|
||||
# if this is the standard primary key named "id", print it as we did with older versions of django_polymorphic
|
||||
if (
|
||||
field.primary_key
|
||||
and field.name == "id"
|
||||
and type(field) == models.AutoField
|
||||
):
|
||||
if field.primary_key and field.name == "id" and type(field) == models.AutoField:
|
||||
out += " " + str(getattr(self, field.name))
|
||||
|
||||
# otherwise, display it just like all other fields (with correct type, shortened content etc.)
|
||||
|
|
@ -109,9 +102,7 @@ class ShowFieldBase:
|
|||
|
||||
# add annotate fields
|
||||
if hasattr(self, "polymorphic_annotate_names"):
|
||||
self._showfields_add_dynamic_fields(
|
||||
self.polymorphic_annotate_names, "Ann", parts
|
||||
)
|
||||
self._showfields_add_dynamic_fields(self.polymorphic_annotate_names, "Ann", parts)
|
||||
|
||||
# add extra() select fields
|
||||
if hasattr(self, "polymorphic_extra_select_names"):
|
||||
|
|
@ -122,9 +113,7 @@ class ShowFieldBase:
|
|||
if self.polymorphic_showfield_deferred:
|
||||
fields = self.get_deferred_fields()
|
||||
if fields:
|
||||
parts.append(
|
||||
(False, "deferred[{}]".format(",".join(sorted(fields))), "")
|
||||
)
|
||||
parts.append((False, "deferred[{}]".format(",".join(sorted(fields))), ""))
|
||||
|
||||
# format result
|
||||
|
||||
|
|
@ -167,19 +156,19 @@ class ShowFieldBase:
|
|||
|
||||
|
||||
class ShowFieldType(ShowFieldBase):
|
||||
""" model mixin that shows the object's class and it's field types """
|
||||
"""model mixin that shows the object's class and it's field types"""
|
||||
|
||||
polymorphic_showfield_type = True
|
||||
|
||||
|
||||
class ShowFieldContent(ShowFieldBase):
|
||||
""" model mixin that shows the object's class, it's fields and field contents """
|
||||
"""model mixin that shows the object's class, it's fields and field contents"""
|
||||
|
||||
polymorphic_showfield_content = True
|
||||
|
||||
|
||||
class ShowFieldTypeAndContent(ShowFieldBase):
|
||||
""" model mixin, like ShowFieldContent, but also show field types """
|
||||
"""model mixin, like ShowFieldContent, but also show field types"""
|
||||
|
||||
polymorphic_showfield_type = True
|
||||
polymorphic_showfield_content = True
|
||||
|
|
|
|||
|
|
@ -19,9 +19,7 @@ class BreadcrumbScope(Node):
|
|||
|
||||
return cls(base_opts=base_opts, nodelist=nodelist)
|
||||
else:
|
||||
raise TemplateSyntaxError(
|
||||
f"{token.contents[0]} tag expects 1 argument"
|
||||
)
|
||||
raise TemplateSyntaxError(f"{token.contents[0]} tag expects 1 argument")
|
||||
|
||||
def render(self, context):
|
||||
# app_label is really hard to overwrite in the standard Django ModelAdmin.
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ def as_script_options(formset):
|
|||
"prefix": formset.prefix,
|
||||
"pkFieldName": formset.model._meta.pk.name,
|
||||
"addText": getattr(formset, "add_text", None)
|
||||
or gettext("Add another %(verbose_name)s")
|
||||
% {"verbose_name": capfirst(verbose_name)},
|
||||
or gettext("Add another %(verbose_name)s") % {"verbose_name": capfirst(verbose_name)},
|
||||
"showAddButton": getattr(formset, "show_add_button", True),
|
||||
"deleteText": gettext("Delete"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
from django.conf import settings
|
||||
from django.urls import include, path
|
||||
from django.contrib.admin import AdminSite
|
||||
from django.contrib.admin.templatetags.admin_urls import admin_urlname
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.messages.middleware import MessageMiddleware
|
||||
from django.http.response import HttpResponse
|
||||
from django.test import RequestFactory, TestCase
|
||||
from django.urls import clear_url_caches, reverse, set_urlconf
|
||||
from django.urls import clear_url_caches, include, path, reverse, set_urlconf
|
||||
|
||||
|
||||
class AdminTestCase(TestCase):
|
||||
|
|
@ -54,7 +53,7 @@ class AdminTestCase(TestCase):
|
|||
|
||||
# Make sure the URLs are reachable by reverse()
|
||||
clear_url_caches()
|
||||
set_urlconf(tuple([path('tmp-admin/', self.admin_site.urls)]))
|
||||
set_urlconf(tuple([path("tmp-admin/", self.admin_site.urls)]))
|
||||
|
||||
def get_admin_instance(self, model):
|
||||
try:
|
||||
|
|
@ -103,9 +102,7 @@ class AdminTestCase(TestCase):
|
|||
Make a direct "add" call to the admin page, circumvening login checks.
|
||||
"""
|
||||
admin_instance = self.get_admin_instance(model)
|
||||
request = self.create_admin_request(
|
||||
"post", self.get_add_url(model) + qs, data=formdata
|
||||
)
|
||||
request = self.create_admin_request("post", self.get_add_url(model) + qs, data=formdata)
|
||||
response = admin_instance.add_view(request)
|
||||
self.assertFormSuccess(request.path, response)
|
||||
return response
|
||||
|
|
@ -176,13 +173,9 @@ class AdminTestCase(TestCase):
|
|||
extra = {"data": {"post": "yes"}}
|
||||
|
||||
admin_instance = self.get_admin_instance(model)
|
||||
request = self.create_admin_request(
|
||||
"post", self.get_delete_url(model, object_id), **extra
|
||||
)
|
||||
request = self.create_admin_request("post", self.get_delete_url(model, object_id), **extra)
|
||||
response = admin_instance.delete_view(request, str(object_id))
|
||||
self.assertEqual(
|
||||
response.status_code, 302, f"Form errors in calling {request.path}"
|
||||
)
|
||||
self.assertEqual(response.status_code, 302, f"Form errors in calling {request.path}")
|
||||
return response
|
||||
|
||||
def create_admin_request(self, method, url, data=None, **extra):
|
||||
|
|
@ -229,9 +222,7 @@ class AdminTestCase(TestCase):
|
|||
self.assertEqual(
|
||||
response.status_code,
|
||||
302,
|
||||
"Form errors in calling {}:\n{}".format(
|
||||
request_url, errors.as_text()
|
||||
),
|
||||
"Form errors in calling {}:\n{}".format(request_url, errors.as_text()),
|
||||
)
|
||||
self.assertTrue(
|
||||
"/login/?next=" not in response["Location"],
|
||||
|
|
|
|||
|
|
@ -726,9 +726,7 @@ class Migration(migrations.Migration):
|
|||
fields=[
|
||||
(
|
||||
"uuid_primary_key",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid1, primary_key=True, serialize=False
|
||||
),
|
||||
models.UUIDField(default=uuid.uuid1, primary_key=True, serialize=False),
|
||||
),
|
||||
("field1", models.CharField(max_length=10)),
|
||||
],
|
||||
|
|
@ -738,9 +736,7 @@ class Migration(migrations.Migration):
|
|||
fields=[
|
||||
(
|
||||
"uuid_primary_key",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid1, primary_key=True, serialize=False
|
||||
),
|
||||
models.UUIDField(default=uuid.uuid1, primary_key=True, serialize=False),
|
||||
),
|
||||
("topic", models.CharField(max_length=30)),
|
||||
],
|
||||
|
|
@ -1721,9 +1717,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name="blogentry",
|
||||
name="blog",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to="tests.BlogA"
|
||||
),
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="tests.BlogA"),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Model2D",
|
||||
|
|
@ -2061,12 +2055,13 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
(
|
||||
"test",
|
||||
models.CharField(
|
||||
max_length=255, default="test_non_polymorphic_parent"
|
||||
),
|
||||
models.CharField(max_length=255, default="test_non_polymorphic_parent"),
|
||||
),
|
||||
],
|
||||
options={"abstract": False, "base_manager_name": "objects",},
|
||||
options={
|
||||
"abstract": False,
|
||||
"base_manager_name": "objects",
|
||||
},
|
||||
bases=("auth.group", models.Model),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@ from django.db.models.query import QuerySet
|
|||
from polymorphic.managers import PolymorphicManager
|
||||
from polymorphic.models import PolymorphicModel
|
||||
from polymorphic.query import PolymorphicQuerySet
|
||||
from polymorphic.showfields import (
|
||||
ShowFieldContent,
|
||||
ShowFieldType,
|
||||
ShowFieldTypeAndContent,
|
||||
)
|
||||
from polymorphic.showfields import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
|
||||
|
||||
|
||||
class PlainA(models.Model):
|
||||
|
|
@ -380,9 +376,7 @@ class ProxyModelB(ProxyModelBase):
|
|||
# with related field 'ContentType.relatednameclash_set'." (reported by Andrew Ingram)
|
||||
# fixed with related_name
|
||||
class RelatedNameClash(ShowFieldType, PolymorphicModel):
|
||||
ctype = models.ForeignKey(
|
||||
ContentType, on_delete=models.CASCADE, null=True, editable=False
|
||||
)
|
||||
ctype = models.ForeignKey(ContentType, on_delete=models.CASCADE, null=True, editable=False)
|
||||
|
||||
|
||||
# class with a parent_link to superclass, and a related_name back to subclass
|
||||
|
|
|
|||
|
|
@ -74,12 +74,8 @@ class MultipleDatabasesTests(TestCase):
|
|||
|
||||
def test_forward_many_to_one_descriptor_on_non_default_database(self):
|
||||
def func():
|
||||
blog = BlogA.objects.db_manager("secondary").create(
|
||||
name="Blog", info="Info"
|
||||
)
|
||||
entry = BlogEntry.objects.db_manager("secondary").create(
|
||||
blog=blog, text="Text"
|
||||
)
|
||||
blog = BlogA.objects.db_manager("secondary").create(name="Blog", info="Info")
|
||||
entry = BlogEntry.objects.db_manager("secondary").create(blog=blog, text="Text")
|
||||
ContentType.objects.clear_cache()
|
||||
entry = BlogEntry.objects.db_manager("secondary").get(pk=entry.id)
|
||||
self.assertEqual(blog, entry.blog)
|
||||
|
|
@ -89,12 +85,8 @@ class MultipleDatabasesTests(TestCase):
|
|||
|
||||
def test_reverse_many_to_one_descriptor_on_non_default_database(self):
|
||||
def func():
|
||||
blog = BlogA.objects.db_manager("secondary").create(
|
||||
name="Blog", info="Info"
|
||||
)
|
||||
entry = BlogEntry.objects.db_manager("secondary").create(
|
||||
blog=blog, text="Text"
|
||||
)
|
||||
blog = BlogA.objects.db_manager("secondary").create(name="Blog", info="Info")
|
||||
entry = BlogEntry.objects.db_manager("secondary").create(blog=blog, text="Text")
|
||||
ContentType.objects.clear_cache()
|
||||
blog = BlogA.objects.db_manager("secondary").get(pk=blog.id)
|
||||
self.assertEqual(entry, blog.blogentry_set.using("secondary").get())
|
||||
|
|
|
|||
|
|
@ -180,9 +180,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
"""
|
||||
UUIDProject.objects.create(topic="John's gathering")
|
||||
UUIDArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")
|
||||
UUIDResearchProject.objects.create(
|
||||
topic="Swallow Aerodynamics", supervisor="Dr. Winter"
|
||||
)
|
||||
UUIDResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
|
||||
|
||||
qs = UUIDProject.objects.all()
|
||||
ol = list(qs)
|
||||
|
|
@ -257,8 +255,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
self.assertIn(
|
||||
"field1",
|
||||
objects_only[3].__dict__,
|
||||
'qs.only("field1") was used, but field1 was incorrectly deferred'
|
||||
" on a child model",
|
||||
'qs.only("field1") was used, but field1 was incorrectly deferred' " on a child model",
|
||||
)
|
||||
self.assertNotIn(
|
||||
"field4", objects_only[3].__dict__, "field4 was not deferred (using only())"
|
||||
|
|
@ -408,10 +405,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
def test_create_instanceof_q(self):
|
||||
q = query_translate.create_instanceof_q([Model2B])
|
||||
expected = sorted(
|
||||
|
||||
ContentType.objects.get_for_model(m).pk
|
||||
for m in [Model2B, Model2C, Model2D]
|
||||
|
||||
ContentType.objects.get_for_model(m).pk for m in [Model2B, Model2C, Model2D]
|
||||
)
|
||||
self.assertEqual(dict(q.children), dict(polymorphic_ctype__in=expected))
|
||||
|
||||
|
|
@ -473,9 +467,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
|
||||
# FIXME: We should not use base_objects here.
|
||||
a = Model2A.base_objects.get(field1="C1")
|
||||
b = One2OneRelatingModelDerived.objects.create(
|
||||
one2one=a, field1="f1", field2="f2"
|
||||
)
|
||||
b = One2OneRelatingModelDerived.objects.create(one2one=a, field1="f1", field2="f2")
|
||||
|
||||
# FIXME: this result is basically wrong, probably due to Django cacheing (we used base_objects), but should not be a problem
|
||||
self.assertEqual(b.one2one.__class__, Model2A)
|
||||
|
|
@ -548,9 +540,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
where=["field1 = 'A1' OR field1 = 'B1'"],
|
||||
order_by=["-id"],
|
||||
)
|
||||
self.assertQuerysetEqual(
|
||||
objects, [Model2B, Model2A], transform=lambda o: o.__class__
|
||||
)
|
||||
self.assertQuerysetEqual(objects, [Model2B, Model2A], transform=lambda o: o.__class__)
|
||||
|
||||
ModelExtraA.objects.create(field1="A1")
|
||||
ModelExtraB.objects.create(field1="B1", field2="B2")
|
||||
|
|
@ -612,9 +602,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
def test_polymorphic___filter(self):
|
||||
self.create_model2abcd()
|
||||
|
||||
objects = Model2A.objects.filter(
|
||||
Q(Model2B___field2="B2") | Q(Model2C___field3="C3")
|
||||
)
|
||||
objects = Model2A.objects.filter(Q(Model2B___field2="B2") | Q(Model2C___field3="C3"))
|
||||
self.assertQuerysetEqual(
|
||||
objects, [Model2B, Model2C], transform=lambda o: o.__class__, ordered=False
|
||||
)
|
||||
|
|
@ -685,12 +673,8 @@ class PolymorphicTests(TransactionTestCase):
|
|||
|
||||
qs = Base.objects.instance_of(ModelX) | Base.objects.instance_of(ModelY)
|
||||
qs = qs.order_by("field_b")
|
||||
self.assertEqual(
|
||||
repr(qs[0]), "<ModelX: id 1, field_b (CharField), field_x (CharField)>"
|
||||
)
|
||||
self.assertEqual(
|
||||
repr(qs[1]), "<ModelY: id 2, field_b (CharField), field_y (CharField)>"
|
||||
)
|
||||
self.assertEqual(repr(qs[0]), "<ModelX: id 1, field_b (CharField), field_x (CharField)>")
|
||||
self.assertEqual(repr(qs[1]), "<ModelY: id 2, field_b (CharField), field_y (CharField)>")
|
||||
self.assertEqual(len(qs), 2)
|
||||
|
||||
def test_multiple_inheritance(self):
|
||||
|
|
@ -715,9 +699,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
obase = RelationBase.objects.create(field_base="base")
|
||||
oa = RelationA.objects.create(field_base="A1", field_a="A2", fk=obase)
|
||||
ob = RelationB.objects.create(field_base="B1", field_b="B2", fk=oa)
|
||||
oc = RelationBC.objects.create(
|
||||
field_base="C1", field_b="C2", field_c="C3", fk=oa
|
||||
)
|
||||
oc = RelationBC.objects.create(field_base="C1", field_b="C2", field_c="C3", fk=oa)
|
||||
oa.m2m.add(oa)
|
||||
oa.m2m.add(ob)
|
||||
|
||||
|
|
@ -809,9 +791,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
|
||||
self.assertIs(type(ModelWithMyManagerNoDefault.my_objects), MyManager)
|
||||
self.assertIs(type(ModelWithMyManagerNoDefault.objects), PolymorphicManager)
|
||||
self.assertIs(
|
||||
type(ModelWithMyManagerNoDefault._default_manager), PolymorphicManager
|
||||
)
|
||||
self.assertIs(type(ModelWithMyManagerNoDefault._default_manager), PolymorphicManager)
|
||||
|
||||
def test_user_objects_manager_as_secondary(self):
|
||||
self.create_model2abcd()
|
||||
|
|
@ -852,19 +832,13 @@ class PolymorphicTests(TransactionTestCase):
|
|||
# This is just a consistency check for now, testing standard Django behavior.
|
||||
parent = PlainParentModelWithManager.objects.create()
|
||||
child = PlainChildModelWithManager.objects.create(fk=parent)
|
||||
self.assertIs(
|
||||
type(PlainParentModelWithManager._default_manager), models.Manager
|
||||
)
|
||||
self.assertIs(type(PlainParentModelWithManager._default_manager), models.Manager)
|
||||
self.assertIs(type(PlainChildModelWithManager._default_manager), PlainMyManager)
|
||||
self.assertIs(type(PlainChildModelWithManager.objects), PlainMyManager)
|
||||
self.assertIs(
|
||||
type(PlainChildModelWithManager.objects.all()), PlainMyManagerQuerySet
|
||||
)
|
||||
self.assertIs(type(PlainChildModelWithManager.objects.all()), PlainMyManagerQuerySet)
|
||||
|
||||
# A related set is created using the model's _default_manager, so does gain extra methods.
|
||||
self.assertIs(
|
||||
type(parent.childmodel_set.my_queryset_foo()), PlainMyManagerQuerySet
|
||||
)
|
||||
self.assertIs(type(parent.childmodel_set.my_queryset_foo()), PlainMyManagerQuerySet)
|
||||
|
||||
# For polymorphic models, the same should happen.
|
||||
parent = ParentModelWithManager.objects.create()
|
||||
|
|
@ -872,9 +846,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
self.assertIs(type(ParentModelWithManager._default_manager), PolymorphicManager)
|
||||
self.assertIs(type(ChildModelWithManager._default_manager), MyManager)
|
||||
self.assertIs(type(ChildModelWithManager.objects), MyManager)
|
||||
self.assertIs(
|
||||
type(ChildModelWithManager.objects.my_queryset_foo()), MyManagerQuerySet
|
||||
)
|
||||
self.assertIs(type(ChildModelWithManager.objects.my_queryset_foo()), MyManagerQuerySet)
|
||||
|
||||
# A related set is created using the model's _default_manager, so does gain extra methods.
|
||||
self.assertIs(type(parent.childmodel_set.my_queryset_foo()), MyManagerQuerySet)
|
||||
|
|
@ -949,8 +921,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
object2 = ProxyModelBase.objects.get(name="object2")
|
||||
self.assertEqual(
|
||||
repr(object1),
|
||||
'<ProxyModelA: id %i, name (CharField) "object1", field1 (CharField) "">'
|
||||
% object1_pk,
|
||||
'<ProxyModelA: id %i, name (CharField) "object1", field1 (CharField) "">' % object1_pk,
|
||||
)
|
||||
self.assertEqual(
|
||||
repr(object2),
|
||||
|
|
@ -964,8 +935,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
objects = list(ProxyModelBase.objects.all().order_by("name"))
|
||||
self.assertEqual(
|
||||
repr(objects[0]),
|
||||
'<ProxyModelA: id %i, name (CharField) "object1", field1 (CharField) "">'
|
||||
% object1_pk,
|
||||
'<ProxyModelA: id %i, name (CharField) "object1", field1 (CharField) "">' % object1_pk,
|
||||
)
|
||||
self.assertEqual(
|
||||
repr(objects[1]),
|
||||
|
|
@ -989,9 +959,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
def test_fix_getattribute(self):
|
||||
# fixed issue in PolymorphicModel.__getattribute__: field name same as model name
|
||||
o = ModelFieldNameTest.objects.create(modelfieldnametest="1")
|
||||
self.assertEqual(
|
||||
repr(o), "<ModelFieldNameTest: id 1, modelfieldnametest (CharField)>"
|
||||
)
|
||||
self.assertEqual(repr(o), "<ModelFieldNameTest: id 1, modelfieldnametest (CharField)>")
|
||||
|
||||
# if subclass defined __init__ and accessed class members,
|
||||
# __getattribute__ had a problem: "...has no attribute 'sub_and_superclass_dict'"
|
||||
|
|
@ -1008,9 +976,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
self.assertEqual(p, t)
|
||||
|
||||
# check that the accessors to parent and sublass work correctly and return the right object
|
||||
p = ModelShow1_plain.objects.non_polymorphic().get(
|
||||
field1="TestParentLinkAndRelatedName"
|
||||
)
|
||||
p = ModelShow1_plain.objects.non_polymorphic().get(field1="TestParentLinkAndRelatedName")
|
||||
# p should be Plain1 and t TestParentLinkAndRelatedName, so not equal
|
||||
self.assertNotEqual(p, t)
|
||||
self.assertEqual(p, t.superclass)
|
||||
|
|
@ -1020,7 +986,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
t.delete()
|
||||
|
||||
def test_polymorphic__aggregate(self):
|
||||
""" test ModelX___field syntax on aggregate (should work for annotate either) """
|
||||
"""test ModelX___field syntax on aggregate (should work for annotate either)"""
|
||||
|
||||
Model2A.objects.create(field1="A1")
|
||||
Model2B.objects.create(field1="A1", field2="B2")
|
||||
|
|
@ -1038,7 +1004,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
)
|
||||
|
||||
def test_polymorphic__complex_aggregate(self):
|
||||
""" test (complex expression on) aggregate (should work for annotate either) """
|
||||
"""test (complex expression on) aggregate (should work for annotate either)"""
|
||||
|
||||
Model2A.objects.create(field1="A1")
|
||||
Model2B.objects.create(field1="A1", field2="B2")
|
||||
|
|
@ -1066,7 +1032,7 @@ class PolymorphicTests(TransactionTestCase):
|
|||
Model2A.objects.aggregate(ComplexAgg("Model2B___field2"))
|
||||
|
||||
def test_polymorphic__filtered_relation(self):
|
||||
""" test annotation using FilteredRelation """
|
||||
"""test annotation using FilteredRelation"""
|
||||
|
||||
blog = BlogA.objects.create(name="Ba1", info="i1 joined")
|
||||
blog.blogentry_set.create(text="bla1 joined")
|
||||
|
|
@ -1079,12 +1045,16 @@ class PolymorphicTests(TransactionTestCase):
|
|||
BlogB.objects.create(name="Bb3")
|
||||
|
||||
result = BlogA.objects.annotate(
|
||||
text_joined=FilteredRelation("blogentry", condition=Q(blogentry__text__contains="joined")),
|
||||
text_joined=FilteredRelation(
|
||||
"blogentry", condition=Q(blogentry__text__contains="joined")
|
||||
),
|
||||
).aggregate(Count("text_joined"))
|
||||
self.assertEqual(result, {"text_joined__count": 3})
|
||||
|
||||
result = BlogA.objects.annotate(
|
||||
text_joined=FilteredRelation("blogentry", condition=Q(blogentry__text__contains="joined")),
|
||||
text_joined=FilteredRelation(
|
||||
"blogentry", condition=Q(blogentry__text__contains="joined")
|
||||
),
|
||||
).aggregate(count=Count("text_joined"))
|
||||
self.assertEqual(result, {"count": 3})
|
||||
|
||||
|
|
@ -1189,18 +1159,24 @@ class PolymorphicTests(TransactionTestCase):
|
|||
)
|
||||
|
||||
def test_bulk_create_ignore_conflicts(self):
|
||||
ArtProject.objects.bulk_create([
|
||||
ArtProject(topic="Painting with Tim", artist="T. Turner"),
|
||||
ArtProject.objects.create(topic="Sculpture with Tim", artist="T. Turner")
|
||||
], ignore_conflicts=True)
|
||||
ArtProject.objects.bulk_create(
|
||||
[
|
||||
ArtProject(topic="Painting with Tim", artist="T. Turner"),
|
||||
ArtProject.objects.create(topic="Sculpture with Tim", artist="T. Turner"),
|
||||
],
|
||||
ignore_conflicts=True,
|
||||
)
|
||||
self.assertEqual(ArtProject.objects.count(), 2)
|
||||
|
||||
def test_bulk_create_no_ignore_conflicts(self):
|
||||
with self.assertRaises(IntegrityError):
|
||||
ArtProject.objects.bulk_create([
|
||||
ArtProject(topic="Painting with Tim", artist="T. Turner"),
|
||||
ArtProject.objects.create(topic="Sculpture with Tim", artist="T. Turner")
|
||||
], ignore_conflicts=False)
|
||||
ArtProject.objects.bulk_create(
|
||||
[
|
||||
ArtProject(topic="Painting with Tim", artist="T. Turner"),
|
||||
ArtProject.objects.create(topic="Sculpture with Tim", artist="T. Turner"),
|
||||
],
|
||||
ignore_conflicts=False,
|
||||
)
|
||||
self.assertEqual(ArtProject.objects.count(), 1)
|
||||
|
||||
def test_can_query_using_subclass_selector_on_abstract_model(self):
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ transform_arg = {"transform": repr} if django.VERSION >= (3, 2) else {}
|
|||
|
||||
class RegressionTests(TestCase):
|
||||
def test_for_query_result_incomplete_with_inheritance(self):
|
||||
""" https://github.com/bconstantin/django_polymorphic/issues/15 """
|
||||
"""https://github.com/bconstantin/django_polymorphic/issues/15"""
|
||||
|
||||
top = Top()
|
||||
top.save()
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@ from polymorphic.tests.models import (
|
|||
Model2C,
|
||||
Model2D,
|
||||
)
|
||||
from polymorphic.utils import (
|
||||
get_base_polymorphic_model,
|
||||
reset_polymorphic_ctype,
|
||||
sort_by_subclass,
|
||||
)
|
||||
from polymorphic.utils import get_base_polymorphic_model, reset_polymorphic_ctype, sort_by_subclass
|
||||
|
||||
|
||||
class UtilsTests(TransactionTestCase):
|
||||
|
|
|
|||
14
pyproject.toml
Normal file
14
pyproject.toml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[tool.isort]
|
||||
profile = "black"
|
||||
line_length = 99
|
||||
|
||||
[tool.black]
|
||||
line-length = 99
|
||||
exclude = '''
|
||||
/(
|
||||
\.git
|
||||
| \.tox
|
||||
| \.venv
|
||||
| dist
|
||||
)/
|
||||
'''
|
||||
13
runtests.py
13
runtests.py
|
|
@ -12,9 +12,7 @@ from django.core.management import execute_from_command_line
|
|||
warnings.simplefilter("always", DeprecationWarning)
|
||||
|
||||
# Give feedback on used versions
|
||||
sys.stderr.write(
|
||||
f"Using Python version {sys.version[:5]} from {sys.executable}\n"
|
||||
)
|
||||
sys.stderr.write(f"Using Python version {sys.version[:5]} from {sys.executable}\n")
|
||||
sys.stderr.write(
|
||||
"Using Django version {} from {}\n".format(
|
||||
django.get_version(), dirname(abspath(django.__file__))
|
||||
|
|
@ -25,9 +23,7 @@ if not settings.configured:
|
|||
settings.configure(
|
||||
DEBUG=False,
|
||||
DATABASES={
|
||||
"default": dj_database_url.config(
|
||||
env="PRIMARY_DATABASE", default="sqlite://:memory:"
|
||||
),
|
||||
"default": dj_database_url.config(env="PRIMARY_DATABASE", default="sqlite://:memory:"),
|
||||
"secondary": dj_database_url.config(
|
||||
env="SECONDARY_DATABASE", default="sqlite://:memory:"
|
||||
),
|
||||
|
|
@ -75,7 +71,7 @@ if not settings.configured:
|
|||
],
|
||||
POLYMORPHIC_TEST_SWAPPABLE="polymorphic.swappedmodel",
|
||||
ROOT_URLCONF=None,
|
||||
SECRET_KEY="supersecret"
|
||||
SECRET_KEY="supersecret",
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -85,8 +81,7 @@ DEFAULT_TEST_APPS = ["polymorphic"]
|
|||
def runtests():
|
||||
other_args = list(filter(lambda arg: arg.startswith("-"), sys.argv[1:]))
|
||||
test_apps = (
|
||||
list(filter(lambda arg: not arg.startswith("-"), sys.argv[1:]))
|
||||
or DEFAULT_TEST_APPS
|
||||
list(filter(lambda arg: not arg.startswith("-"), sys.argv[1:])) or DEFAULT_TEST_APPS
|
||||
)
|
||||
argv = sys.argv[:1] + ["test", "--traceback"] + other_args + test_apps
|
||||
execute_from_command_line(argv)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user