1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Django modelformsetにはまった人

Posted at

初めに

複数の同じformを入力する際にformsetを使用し実装を行うときにいくつかハマったので
メモを残す。

例:

以下のコードが今回formsetを使用するmodel, form, viewです。
内容は適当なので気にしないでください。


# model
class User(models.Model):
   id = models.BigAutoField(primary_key=True)
   name = models.CharField(null=False, max_length=100)
   ...
   created_at = models.DateTimeField(auto_now_add=True)
   updated_at = models.DateTimeField(auto_now=True)

# form 
class UserForm(forms.ModelForm):
   use_required_attribute = False

   name = forms.CharField(...)
   ...
   class Meta:
      model = User
      fields = [ 'name', ...]

# view
class UserView(UpdateView):
  template_name = 'user_setting.html'
  model = User
  form_class = UserForm
  FormSet = modelformset_factory(User, form=UserForm, extra=0)

  def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     context['formset'] = self.FormSet(queryset=User.objects.filter(...).all())
     return context

  def form_valide(self, f):
     formset = self.FormSet(self.request.POST)
     if formset.is_valid():
       ....
     return redirect(self.get_cuccess_url())

HTMLはこんな感じ

...
<!-- 入力欄 --->
{% csrf_token %}
{% for field in formset %}
  {{ field.name }}
  <!-- 他の項目 -->
{% endfor %}
...

事象1: ManagementFormデータが見つからないか、改竄されています

ManagementFormデータってなんぞやという感じで色々探したら、以下のようにformset.management_formを挿入すれば良いとの事

改善策:

<!-- 入力欄 --->
{% csrf_token %}
{{ formset.management_form }}
{% for field in formset %}
  {{ field.name }}
  <!-- 他の項目 -->
{% endfor %}

事象2:'id':['このフィールドは必須です。']

idってなにformの何処にも定義してないんだけどーって思いながらハマっていました。
よく見たらformsetに格納されているformにinstance設定されていないし。。。

改善策1:

{% csrf_token %}
{{ formset.management_form }}
{% for field in formset %}
  <!-- instance情報が隠れているので追加する必要がある -->
  {% for hidden in field.hidden_fields %}
    {{ hidden }}
  {% endfor %}
  <!-- ここまで -->
  {{ field.name }}
  <!-- 他の項目 -->
{% endfor %}

改善策2:

{% csrf_token %}
{{ formset.management_form }}
{% for field in formset %}
  <!-- instance情報が隠れているので追加する必要がある -->
  {{ field.id }}
  <!-- ここまで -->
  {{ field.name }}
  <!-- 他の項目 -->
{% endfor %}
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?