3

django-hvad を使用して、さまざまな言語でオブジェクトを編集しています。ドキュメントで説明されているように、フォーム (オブジェクト用) とフォームセット (さまざまな言語のオブジェクト属性用) を取得しました。フォームセットは、django-crispy-forms でビルドされた言語ごとのタブに表示されます。

イニシャルを使用しない限り、すべて正常に機能します。私の目標は、言語を事前に選択し、language_code-field を非表示にして、複数の言語を入力できるようにすることですが、その必要はありませ

フォーム.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 で定義されているのと同じ順序でイニシャルを設定している限り機能しますが、2 番目のタブ/言語のみを入力すると、重複する言語が生成される可能性があります。ビューをリロードすると、両方の最初のタブが 2 番目の言語で埋められます。 . 最初のものはフォームセットに事前入力されたフォームのため、2 つ目はイニシャルのためです。

ビュー.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
            })

Category-model と Category フォームはほぼ標準なので、添付しません。誰かが同様の問題に遭遇したり、1つの重要な質問の解決策を提供したりする可能性があるかどうか、私は本当に興味があります: どうすればフォームセットでイニシャルを動的に設定できますか?

乾杯、マリウス

4

0 に答える 0