我正在使用django-hvad编辑不同语言的对象。我得到了一个表单(用于对象)和一个formset(用于不同语言的对象属性),如documentation中所述。 formset显示在每种语言的选项卡中,使用django-crispy-forms构建。
只要我不使用缩写,一切正常。我的目标是预先选择语言并隐藏language_code-field,这样可能输入多种语言,但你 :
forms.py:
languages = [x[0] for x in settings.LANGUAGES]
class MyTitleTranslationForm(forms.ModelForm):
# language_code = forms.CharField()
class Meta:
fields = ['title'] # , 'language_code'
def __init__(self, *args, **kwargs):
super(MyTitleTranslationForm, self).__init__(*args, **kwargs)
# self.fields['language_code'].widget = forms.HiddenInput()
# Crispy
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.label_class = 'col-md-3'
self.helper.field_class = 'col-md-9'
self.helper.layout = Layout(
Div('id', 'title', 'language_code', 'DELETE',
role="tabpanel", css_class="tab-pane", css_id=self.initial.get('language_code'))
)
class MyBaseTranslationFormSet(BaseTranslationFormSet):
def __init__(self, *args, **kwargs):
super(MyBaseTranslationFormSet, self).__init__(*args, **kwargs)
self.used_language_codes = []
self.languages = []
actual_language = False
counter = 0
for form in self.forms:
if form.instance.id:
actual_language = form.initial.get('language_code', 'de')
else:
for language in languages:
if language not in self.used_language_codes:
actual_language = language
break
self.used_language_codes.append(actual_language)
self.languages.append({
'language': actual_language,
'error': bool(form.errors)
})
# DANGEROUS LINE
form.fields['language_code'].initial = actual_language
form.helper.layout.fields[0].css_id = actual_language
if counter == 0:
form.helper.layout.fields[0].css_class += " active"
counter += 1
在django-hvad的某处,首字母再次设置或覆盖,因此表单绑定。这会导致数据无效,因为未填写每种语言的内容字段。 只要我按照settings.LANGUAGES中定义的顺序设置首字母就行,但如果你只填写第二个标签/语言,这可能会产生重复的语言: 如果重新加载视图,则第一个选项卡都将填充第二种语言。第一个是因为formset中的预填充形式,而第二个是因为初始化。
views.py:
class CategoryEditView(TranslatableUpdateViewMixin, UpdateView):
model = Category
success_url = reverse_lazy('category:list-view')
form_class = modelform_factory(Category, form=CategoryForm)
translationformset_class = translationformset_factory(Category, form=MyTitleTranslationForm,
formset=MyBaseTranslationFormSet,
extra=len(settings.LANGUAGES),
max_num=len(settings.LANGUAGES))
def get_context_data(self, **kwargs):
context = super(_TranslatableViewMixin, self).get_context_data(**kwargs)
context['translationformset'] = self.translationformset_class(instance=self.object)
return context
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request.FILES, instance=self.object)
translationformset = self.translationformset_class(request.POST, request.FILES, instance=self.object)
if form.is_valid() and translationformset.is_valid():
self.object = form.save(commit=False)
translationformset.instance = self.object
translationformset.save()
self.object.save()
form.save_m2m()
return redirect(self.get_success_url())
else:
return render(request, self.get_template_names(), {
'form': form,
'translationformset': translationformset
})
类别模型和类别表单非常标准,所以我不附加它们。 我真的很好奇是否有人遇到类似问题或者甚至可能为一个关键问题提供解决方案:如何动态设置表单中的首字母?
干杯, 的Marius