Skip to content

Commit

Permalink
Revert "Form improvements (#5837)"
Browse files Browse the repository at this point in the history
This reverts commit 0d193d8.
  • Loading branch information
SchrodingersGat committed Nov 14, 2023
1 parent 2fcd6ae commit 9714d4c
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 354 deletions.
12 changes: 0 additions & 12 deletions InvenTree/InvenTree/metadata.py
Expand Up @@ -10,7 +10,6 @@
import InvenTree.permissions
import users.models
from InvenTree.helpers import str2bool
from InvenTree.serializers import DependentField

logger = logging.getLogger('inventree')

Expand Down Expand Up @@ -243,10 +242,6 @@ def get_field_info(self, field):
We take the regular DRF metadata and add our own unique flavor
"""
# Try to add the child property to the dependent field to be used by the super call
if self.label_lookup[field] == 'dependent field':
field.get_child(raise_exception=True)

# Run super method first
field_info = super().get_field_info(field)

Expand Down Expand Up @@ -280,11 +275,4 @@ def get_field_info(self, field):
else:
field_info['api_url'] = model.get_api_url()

# Add more metadata about dependent fields
if field_info['type'] == 'dependent field':
field_info['depends_on'] = field.depends_on

return field_info


InvenTreeMetadata.label_lookup[DependentField] = "dependent field"
88 changes: 0 additions & 88 deletions InvenTree/InvenTree/serializers.py
Expand Up @@ -2,7 +2,6 @@

import os
from collections import OrderedDict
from copy import deepcopy
from decimal import Decimal

from django.conf import settings
Expand Down Expand Up @@ -95,93 +94,6 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)


class DependentField(serializers.Field):
"""A dependent field can be used to dynamically return child fields based on the value of other fields."""
child = None

def __init__(self, *args, depends_on, field_serializer, **kwargs):
"""A dependent field can be used to dynamically return child fields based on the value of other fields.
Example:
This example adds two fields. If the client selects integer, an integer field will be shown, but if he
selects char, an char field will be shown. For any other value, nothing will be shown.
class TestSerializer(serializers.Serializer):
select_type = serializers.ChoiceField(choices=[
("integer", "Integer"),
("char", "Char"),
])
my_field = DependentField(depends_on=["select_type"], field_serializer="get_my_field")
def get_my_field(self, fields):
if fields["select_type"] == "integer":
return serializers.IntegerField()
if fields["select_type"] == "char":
return serializers.CharField()
"""
super().__init__(*args, **kwargs)

self.depends_on = depends_on
self.field_serializer = field_serializer

def get_child(self, raise_exception=False):
"""This method tries to extract the child based on the provided data in the request by the client."""
data = deepcopy(self.context["request"].data)

def visit_parent(node):
"""Recursively extract the data for the parent field/serializer in reverse."""
nonlocal data

if node.parent:
visit_parent(node.parent)

# only do for composite fields and stop right before the current field
if hasattr(node, "child") and node is not self and isinstance(data, dict):
data = data.get(node.field_name, None)
visit_parent(self)

# ensure that data is a dictionary and that a parent exists
if not isinstance(data, dict) or self.parent is None:
return

# check if the request data contains the dependent fields, otherwise skip getting the child
for f in self.depends_on:
if not data.get(f, None):
return

# partially validate the data for options requests that set raise_exception while calling .get_child(...)
if raise_exception:
validation_data = {k: v for k, v in data.items() if k in self.depends_on}
serializer = self.parent.__class__(context=self.context, data=validation_data, partial=True)
serializer.is_valid(raise_exception=raise_exception)

# try to get the field serializer
field_serializer = getattr(self.parent, self.field_serializer)
child = field_serializer(data)

if not child:
return

self.child = child
self.child.bind(field_name='', parent=self)

def to_internal_value(self, data):
"""This method tries to convert the data to an internal representation based on the defined to_internal_value method on the child."""
self.get_child()
if self.child:
return self.child.to_internal_value(data)

return None

def to_representation(self, value):
"""This method tries to convert the data to representation based on the defined to_representation method on the child."""
self.get_child()
if self.child:
return self.child.to_representation(value)

return None


class InvenTreeModelSerializer(serializers.ModelSerializer):
"""Inherits the standard Django ModelSerializer class, but also ensures that the underlying model class data are checked on validation."""

Expand Down
5 changes: 2 additions & 3 deletions InvenTree/label/api.py
Expand Up @@ -159,8 +159,7 @@ def get_serializer(self, *args, **kwargs):
# Check the request to determine if the user has selected a label printing plugin
plugin = self.get_plugin(self.request)

kwargs.setdefault('context', self.get_serializer_context())
serializer = plugin.get_printing_options_serializer(self.request, *args, **kwargs)
serializer = plugin.get_printing_options_serializer(self.request)

# if no serializer is defined, return an empty serializer
if not serializer:
Expand Down Expand Up @@ -227,7 +226,7 @@ def print(self, request, items_to_print):
raise ValidationError('Label has invalid dimensions')

# if the plugin returns a serializer, validate the data
if serializer := plugin.get_printing_options_serializer(request, data=request.data, context=self.get_serializer_context()):
if serializer := plugin.get_printing_options_serializer(request, data=request.data):
serializer.is_valid(raise_exception=True)

# At this point, we offload the label(s) to the selected plugin.
Expand Down

0 comments on commit 9714d4c

Please sign in to comment.