Пользовательское поле модели MultiInput в Django
Я пытаюсь создать пользовательское поле для объема, состоящее из 4 частей (длина, ширина, высота и единицы измерения). Я думаю, что расширение класса models.JSONField имеет наибольший смысл.
Вот что у меня есть на данный момент.
inventory/models.py
from django.db import models
from tpt.fields import VolumeField
class Measurement(models.Model):
volumne = VolumeField()
tpt/fields.py
from django.db import models
from tpt import forms
class VolumeField(models.JSONField):
description = 'Package volume field in 3 dimensions'
def __init__(self, length=None, width=None, height=None, units=None, *args, **kwargs):
self.widget_args = {
"length": length,
"width": width,
"height": height,
"unit_choices": units,
}
super(VolumeField, self).__init__(*args, **kwargs)
def formfield(self, **kwargs):
defaults = {"form_class": forms.VolumeWidgetField}
defaults.update(kwargs)
defaults.update(self.widget_args)
return super(VolumeField, self).formfield(**defaults)
tpt/forms.py
import json
from django import forms
class VolumeWidget(forms.widgets.MultiWidget):
def __init__(self, attrs=None):
widgets = [forms.NumberInput(),
forms.NumberInput(),
forms.NumberInput(),
forms.TextInput()]
super(VolumeWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
return json.loads(value)
else:
return [0, 0, 0, '']
class VolumeWidgetField(forms.fields.MultiValueField):
widget = VolumeWidget
def __init__(self, *args, **kwargs):
list_fields = [forms.fields.CharField(max_length=8),
forms.fields.CharField(max_length=8),
forms.fields.CharField(max_length=8),
forms.fields.CharField(max_length=4)]
super(VolumeWidgetField, self).__init__(list_fields, *args, **kwargs)
def compress(self, values):
return json.dumps(values)
Я смог запустить сервер, но когда я пытаюсь добавить новую запись в модель измерений в Admin, я получаю эту ошибку:
Я пробовал расширить models.CharField для тестирования, но получаю ошибку CharFields must define a 'max_length' attribute.
, а когда я указываю max_length, то получаю результат, аналогичный JSONField, но с max_length
вместо encode
: TypeError: Field.__init__() got an unexpected keyword argument 'max_length'
Есть идеи, что я делаю не так?
Спасибо
После небольшого расследования я обнаружил, что причиной проблемы была передача kwargs обратно в класс VolumeWidgetField
. Простое удаление этого элемента позволило коду работать так, как ожидалось.
Вот обновленный tpt/forms.py
import json
from django import forms
class VolumeWidget(forms.widgets.MultiWidget):
def __init__(self, attrs=None):
widgets = [forms.NumberInput(),
forms.NumberInput(),
forms.NumberInput(),
forms.TextInput()]
super(VolumeWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
return json.loads(value)
else:
return [0, 0, 0, '']
class VolumeWidgetField(forms.fields.MultiValueField):
widget = VolumeWidget
def __init__(self, *args, **kwargs):
list_fields = [forms.fields.CharField(max_length=8),
forms.fields.CharField(max_length=8),
forms.fields.CharField(max_length=8),
forms.fields.CharField(max_length=4)]
super(VolumeWidgetField, self).__init__(list_fields, *args)
def compress(self, values):
return json.dumps(values)