replace the custom Graphene mutation `RetrieveExactProducts` with a unified DRF implementation using `inline_serializer`. Updated GraphQL schema to resolve `retrieve_exact_products` query using a standardized approach. This change improves consistency across DRF and GraphQL APIs, reduces duplicate logic, and centralizes request validations.
62 lines
2 KiB
Python
62 lines
2 KiB
Python
import json
|
|
from typing import Any, Mapping
|
|
|
|
from django import forms
|
|
from django.core.files.uploadedfile import UploadedFile
|
|
from django.forms.renderers import BaseRenderer
|
|
from django.forms.widgets import PasswordInput
|
|
from django.utils.datastructures import MultiValueDict
|
|
from django.utils.safestring import SafeString
|
|
|
|
|
|
class PasswordInputRenderValue(PasswordInput):
|
|
"""PasswordInput with render_value=True so constance re-displays the current value."""
|
|
|
|
def __init__(self, attrs=None):
|
|
super().__init__(attrs=attrs, render_value=True)
|
|
|
|
|
|
class JSONTableWidget(forms.Widget):
|
|
template_name = "json_table_widget.html"
|
|
|
|
def format_value(self, value: str | dict[str, Any]) -> str | dict[str, Any]: # ty: ignore[invalid-method-override]
|
|
if isinstance(value, dict):
|
|
return value
|
|
try:
|
|
if isinstance(value, str):
|
|
value = json.loads(value)
|
|
except json.JSONDecodeError:
|
|
value = {}
|
|
return value
|
|
|
|
def render(
|
|
self,
|
|
name: str,
|
|
value: str | dict[str, Any],
|
|
attrs: dict[str, Any] | None = None,
|
|
renderer: BaseRenderer | None = None,
|
|
) -> SafeString:
|
|
value = self.format_value(value)
|
|
return super().render(name, value, attrs, renderer)
|
|
|
|
def value_from_datadict(
|
|
self,
|
|
data: Mapping[str, Any],
|
|
files: MultiValueDict[str, UploadedFile],
|
|
name: str,
|
|
) -> str | None:
|
|
json_data = {}
|
|
|
|
try:
|
|
keys = data.getlist(f"{name}_key") # ty: ignore[unresolved-attribute]
|
|
values = data.getlist(f"{name}_value") # ty: ignore[unresolved-attribute]
|
|
for key, value in zip(keys, values, strict=True):
|
|
if key.strip():
|
|
try:
|
|
json_data[key] = json.loads(value)
|
|
except (json.JSONDecodeError, ValueError):
|
|
json_data[key] = value
|
|
except TypeError:
|
|
pass
|
|
|
|
return None if not json_data else json.dumps(json_data)
|