This commit introduces support for uploading optional video files to products and image files to blog posts. Enhanced admin interfaces were added to preview these files directly. Also includes adjustments to GraphQL types and serializers to expose the new fields.
63 lines
2.1 KiB
Python
63 lines
2.1 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=False):
|
|
key = key.strip()
|
|
if key:
|
|
try:
|
|
json_data[key] = json.loads(value)
|
|
except (json.JSONDecodeError, ValueError):
|
|
json_data[key] = value
|
|
except (TypeError, AttributeError):
|
|
pass
|
|
|
|
return None if not json_data else json.dumps(json_data)
|