django formset 데이터 시트 의 대량 작업 을 위 한 예제 코드

formset 이란 무엇 입 니까?
forms 구성 요 소 는 폼 검증 에 사용 되 는 것 을 알 고 있 습 니 다.좀 더 정확하게 말하자면 forms 구성 요 소 는 데이터베이스 시트 의 한 줄 기록 을 검증 하 는 데 사 용 됩 니 다.formset 구성 요소 가 다 릅 니 다.formset 는 같은 과 에서 동시에 검증 표 의 여러 줄 기록 입 니 다.즉,formset 는 폼 을 대량으로 검증 하 는 구성 요소 입 니 다.
대량 추가
먼저 formset 대상 을 예화 해 야 합 니 다.대상 이 초기 화 될 때 조작 표 의 forms 폼 류,파 라 메 터 를 제공 해 야 합 니 다. extra 는 몇 줄 의 데 이 터 를 검증 하 는 데 사 용 됩 니 다.실례 화 된 formset 대상 을 전단 페이지 에 전달 하고 전단 템 플 릿 은 2 층 순환 을 통 해 1 층 순환 form,2 층 순환 form 의 필드 입 니 다.GET 요청 시,실례 화 된 formset 대상 을 전단 에 직접 전달 합 니 다.POST 가 요청 할 때 폼 을 대량으로 검증 하고 모든 데이터 에 문제 가 없 을 때 배경 데이터 베 이 스 는 데 이 터 를 저장 합 니 다.
배경 에 데 이 터 를 저장 할 때 두 가지 방식 이 있 습 니 다.첫 번 째 방식 은 간결 하지만 필드 에서 유일 하 게 제약 하 는 오 류 를 포착 할 수 없습니다.따라서 formset 를 사용 하여 데 이 터 를 대량으로 추가 할 때 두 번 째 방식 을 사용 하 는 것 이 좋 습 니 다.유일한 제약 오류 정 보 를 수 동 으로 캡 처 하여 formset 에 전단 페이지 로 보 내 는 것 이 좋 습 니 다.

models.Permission.objects.create(**row)
obj = models.Permission(**row) | obj.save()
오류 정보 캡 처 를 제약 하 는 유일한 과정 입 니 다.사용 해 야 합 니 다. obj.validate_유 니 크()는 이 대상 이 유일한 제약 을 만족 시 키 는 지 판단 하고 만족 하지 않 으 면 이상 캡 처 작업 을 통 해 이상 정 보 를 캡 처 합 니 다.통과 하 다. formset.errors[i].update(e)는 잘못된 정 보 를 formset 에 넣 어 전단 페이지 로 보 냅 니 다.forms 구성 요소 의 검증 을 통 해 유일한 제약 오 류 를 포착 할 수 없 기 때 문 입 니 다.따라서 잘못된 정 보 를 수 동 으로 수집 하여 forset 에 넣 습 니 다.
또한 전단 페이지 에 표 시 된 폼 이 데 이 터 를 작성 하지 않 으 면 직접 제출 하 는 것 이 잘못 되 지 않 습 니 다. formset 기본 값 은 필드 를 바 꾸 지 않 으 면 이 줄 의 데 이 터 를 검증 하지 않 습 니 다.한 필드 만 작성 하면 이 줄 의 데 이 터 는 폼 검증 을 할 것 이다.

# views.py
def multi_add(request):
  """
      
  :param request:
  :return:
  """
  formset_class = formset_factory(MultiPermissionForm, extra=2)

  if request.method == 'GET':
    formset = formset_class()
    return render(request, 'multi_add.html', {'formset': formset})

  formset = formset_class(data=request.POST)
  if formset.is_valid():
    flag = True
    #   formset       ,            。
    post_row_list = formset.cleaned_data 
    for i in range(0, formset.total_form_count()):
      row = post_row_list[i]
      if not row:
        continue
      try:
        obj = models.Permission(**row)
        obj.validate_unique() #                    。
        obj.save()
      except Exception as e:
        formset.errors[i].update(e)
        flag = False
    if flag:
      return HttpResponse('    ')
    else:
      return render(request, 'multi_add.html', {'formset': formset})
  return render(request, 'multi_add.html', {'formset': formset})

전단 템 플 릿 은 2 층 순환 을 통 해 1 층 순환 formset 는 모든 form 을 얻 고 2 층 순환 form 은 모든 필드 를 얻 습 니 다.forms 구성 요소 와 마찬가지 로 form 폼 과 input 제출 수 단추 및 csrf 를 수 동 으로 추가 해 야 합 니 다.token 크로스 도 메 인 위조 요청.이 밖 에 formset 를 사용 하려 면 추가 가 필요 합 니 다. {{ formset.management_form},어떤 formset 를 사용 하면 formset.management 를 추가 합 니 다.form.

# multi_add.html
<form method="post">
  {% csrf_token %}
  {{ formset.management_form }}
  <table border="1">
    <thead>
    <tr>
      <th>  </th>
      <th>URL</th>
      <th>NAME</th>
      <th>  </th>
      <th>   </th>
    </tr>
    </thead>
    <tbody>
    {% for form in formset %}
      <tr>
        {% for field in form %}
          <td>{{ field }} <span style="color: red;">{{ field.errors.0 }}</span></td>
        {% endfor %}
      </tr>
    {% endfor %}
    </tbody>
  </table>
  <input type="submit" value="  ">
</form>
일괄 편집
대량 편집 과 대량 증 가 는 대체로 일치 하지만 사용 차이 가 있 습 니 다.formset 대상 을 예화 할 때 기본 extra=1 을 수 동 으로 extra=0 으로 수정 해 야 합 니 다.GET 요청,페이지 는 기본 값 을 표시 해 야 합 니 다.매개 변수 initial 할당 목록 내부 에 사전 이 포 함 된 데이터 구조의 데 이 터 를 사용 해 야 합 니 다. 또한 줄 마다 데 이 터 를 전달 하 는 id 가 필요 합 니 다.formset 에서 수정 해 야 할 데이터 id 를 알려 줍 니 다.이 때 사용 하 는 forms 클래스 는 대량으로 사용 하 는 클래스 보다 id 필드 가 많 습 니 다. id=forms.IntegerField(widget=forms.HiddenInput()),기본 숨겨 진 필드,전단 페이지 가 표시 되 지 않 습 니 다.
마찬가지 로 유일한 제약 오류 가 발생 할 수 있 습 니 다.순환 과 반 사 를 사용 하여 각 필드 에 데이터 업데이트 할당 을 한 다음 에 데이터 베 이 스 를 제출 하여 저장 합 니 다.

def multi_edit(request):
  formset_class = formset_factory(MultiUpdatePermissionForm, extra=0)
  if request.method == 'GET':
    formset = formset_class(
      initial=models.Permission.objects.all().values('id', 'title', 'name', 'url', 'menu_id', 'pid_id'))
    return render(request, 'multi_edit.html', {'formset': formset})

  formset = formset_class(data=request.POST)
  if formset.is_valid():
    #   formset       ,            。
    post_row_list = formset.cleaned_data 
    flag = True
    for i in range(0, formset.total_form_count()):
      row = post_row_list[i]
      if not row:
        continue
      permission_id = row.pop('id')
      try:
        permission_object = models.Permission.objects.filter(id=permission_id).first()
        for key, value in row.items():
          setattr(permission_object, key, value)
        permission_object.validate_unique()
        permission_object.save()

      except Exception as e:
        formset.errors[i].update(e)
        flag = False
    if flag:
      return HttpResponse('    ')
    else:
      return render(request, 'multi_edit.html', {'formset': formset})
  return render(request, 'multi_edit.html', {'formset': formset})

전단 템 플 릿 이 각 필드 를 순환 적 으로 표시 할 때 첫 번 째 id 필드 인지 여 부 를 판단 하고 첫 번 째 필드 라면 바로 {{field}}페이지 가 표시 되 지 않 습 니 다.

<form method="post">
  {% csrf_token %}
  {{ formset.management_form }}
  <table border="1">
    <thead>
    <tr>
      <th>  </th>
      <th>URL</th>
      <th>NAME</th>
      <th>  </th>
      <th>   </th>
    </tr>
    </thead>
    <tbody>
    {% for form in formset %}
      <tr>
        {% for field in form %}
          {% if forloop.first %}
            {{ field }}
          {% else %}
            <td>{{ field }} <span style="color: red;">{{ field.errors.0 }}</span></td>
          {% endif %}
        {% endfor %}
      </tr>
    {% endfor %}
    </tbody>
  </table>
  <input type="submit" value="  ">
</form>

이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기