У меня есть Form
. Я хочу включить скрытое поле, которое возвращает модель. Я поставлю значение в представлении; Мне просто нужно, чтобы он был опубликован на следующей странице.
Какое поле я должен использовать в классе формы?
У меня есть Form
. Я хочу включить скрытое поле, которое возвращает модель. Я поставлю значение в представлении; Мне просто нужно, чтобы он был опубликован на следующей странице.
Какое поле я должен использовать в классе формы?
Скрытое поле, возвращающее модель? Итак, идентификатор экземпляра модели?
Виджет forms.HiddenInput
должен делать трюк, будь то в поле FK или CharField, вы помещаете идентификатор экземпляра модели.
class MyForm(forms.Form):
hidden_2 = forms.CharField(widget=forms.HiddenInput())
hidden_css = forms.CharField(widget=forms.MostWidgets(attrs={'style': 'display:none;'}))
Я полагаю, что самый быстрый способ получить эту работу -
class MyForm(forms.Form):
model_instance = forms.ModelChoiceField(queryset=MyModel.objects.all(), widget=forms.HiddenInput())
form = MyForm({'model_instance': '1'})
form.cleaned_data['model_instance']
Но мне не нравится идея поставки MyModel.objects.all(), если вы собираетесь указать один элемент в любом случае.
Похоже, чтобы избежать такого поведения, вам придется переопределить форму __init__
с меньшим QuerySet
.
Я думаю, что предпочитаю старомодный способ:
class MyForm(forms.Form):
model_instance = forms.CharField(widget=forms.HiddenInput())
def clean_model_instance(self):
data = self.cleaned_data['model_instance']
if not data:
raise forms.ValidationError()
try:
instance = MyModel.objects.get(id=data)
except MyModel.DoesNotExist:
raise forms.ValidationError()
return instance
Подход в ответе Yuji использует метод clean_model_instance
в форме, который хорош, если вы только когда-либо делаете это один раз в своей базе кода. Если вы делаете это чаще, то вам может пригодиться реализация пользовательского поля модели.
Это код, который у меня есть:
from django import forms
class ModelField(forms.Field):
Model = None
def prepare_value(self, value):
"""Inject entities' id value into the form html data"""
if isinstance(value, self.Model):
return value.id
return value
def to_python(self, value):
"""More or less stolen from ModelChoiceField.to_python"""
if value in self.empty_values:
return None
try:
value = self.Model.objects.get(id=value)
except (ValueError, self.Model.DoesNotExist):
raise forms.ValidationError('%s does not exist'
% self.Model.__class__.__name__.capitalize())
return value
Если вы используете это как базовый класс, а затем специализируетесь на своих моделях, то он становится полезным. Например:
# In app/fields.py
from .models import CustomModel
class CustomModelField(ModelField):
Model = CustomModel
Затем вы можете связать это с любым виджетом, который вам нужен:
# in app/forms.py
class MyForm(forms.Form):
hidden_custom_model_field = CustomModelField(widget=forms.HiddenInput())
other_widget_custom_model_field = CustomModelField(widget=MyCustomWidget())