Skip to content

Commit

Permalink
feat: add instance for model form
Browse files Browse the repository at this point in the history
  • Loading branch information
amaury.lerouxdupeyron committed Sep 12, 2024
1 parent 8698366 commit 7e3a50e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
16 changes: 12 additions & 4 deletions admin_action_tools/admin/form_tool.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import functools
from importlib import import_module
from typing import Callable, Dict
from typing import Callable, Dict, Optional, Type

from django import forms
from django.contrib.admin import helpers
Expand Down Expand Up @@ -80,11 +80,11 @@ def run_form_tool(
if step == ToolAction.BACK:
# cancel ask, revert to previous form
data = tool_chain.rollback()
form_instance = form(data)
form_instance = self.get_instance(form, data=data, instance=queryset_or_object)
# First called by `Go` which would not have tool_name in params
elif step == ToolAction.CONFIRMED:
# form is filled
form_instance = form(request.POST)
form_instance = self.get_instance(form, data=request.POST, instance=queryset_or_object)
if form_instance.is_valid():
metadata = self.__get_metadata(form)
tool_chain.set_tool(tool_name, form_instance.data, metadata=metadata)
Expand All @@ -93,14 +93,22 @@ def run_form_tool(
# forward to next
return func(self, request, queryset_or_object)
else:
form_instance = form()
form_instance = self.get_instance(form, instance=queryset_or_object)

queryset: QuerySet = self.to_queryset(request, queryset_or_object)
context = self.build_context(request, func, queryset, form_instance, tool_name, display_queryset)

# Display form
return self.render_action_form(request, context)

@staticmethod
def get_instance(
form: Type[forms.BaseForm], data: Optional[dict] = None, instance: Optional[forms.BaseForm] = None
) -> forms.BaseForm:
if issubclass(form, forms.ModelForm): # pylint: disable=E721
return form(data, instance=instance)
return form(data)


def add_form_to_action(form: Form, display_queryset=True):
"""
Expand Down
27 changes: 27 additions & 0 deletions admin_action_tools/tests/unit/form-tool/test_form_action.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from unittest import mock

from django import forms
from django.contrib.auth.models import User
from django.urls import reverse

from admin_action_tools.admin.form_tool import ActionFormMixin
from admin_action_tools.constants import CONFIRM_FORM
from admin_action_tools.tests.helpers import AdminConfirmTestCase
from tests.factories import InventoryFactory, ShopFactory
Expand Down Expand Up @@ -77,3 +81,26 @@ def test_form_action_with_not_valid_form(self):

self.assertIn("Configure the", response.rendered_content)
self.assertIn("This field is required.", response.rendered_content)

def test_get_instance_with_model_form(self) -> None:
form_data = mock.MagicMock(spec=dict)
model_instance = mock.MagicMock()

model_form_class = forms.modelform_factory(ShopFactory, forms.ModelForm)
form_instance = ActionFormMixin.get_instance(model_form_class, data=form_data, instance=model_instance)

self.assertIsInstance(form_instance, model_form_class)
self.assertEqual(form_instance.data, form_data)
self.assertEqual(form_instance.instance, model_instance)
self.assertIsInstance(form_instance, model_form_class)

def test_get_instance_with_form(self) -> None:
form_data = mock.MagicMock(spec=dict)

form_class = forms.Form
form_instance = ActionFormMixin.get_instance(form_class, data=form_data)

self.assertIsInstance(form_instance, form_class)
self.assertEqual(form_instance.data, form_data)
self.assertFalse(hasattr(form_instance, "instance"))
self.assertIsInstance(form_instance, form_class)

0 comments on commit 7e3a50e

Please sign in to comment.