最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

django formset實現(xiàn)數(shù)據(jù)表的批量操作的示例代碼

 更新時間:2019年12月06日 08:31:07   作者:liuxu2019  
這篇文章主要介紹了django-formset實現(xiàn)數(shù)據(jù)表的批量操作的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

什么是formset

我們知道forms組件是用來做表單驗證,更準(zhǔn)確一點說,forms組件是用來做數(shù)據(jù)庫表中一行記錄的驗證。有forms組件不同,formset是同科同時驗證表中的多行記錄,即formset是做表單批量驗證的組件。

批量添加

首先要實例化formset對象,對象初始化時需要提供操作表的forms表單類,參數(shù) extra 用來顯示驗證幾行數(shù)據(jù)。將實例化的formset對象傳遞給前端頁面,前端模板通過兩層循環(huán):第一層循環(huán)form,第二層循環(huán)form中的字段。當(dāng)GET請求時,直接將實例化的formset對象傳遞給前端。當(dāng)POST請求時,批量驗證表單,當(dāng)所有數(shù)據(jù)都沒有問題時,后臺數(shù)據(jù)庫保存數(shù)據(jù)。

后臺保存數(shù)據(jù)時,有兩種方式:第一種方式簡潔,但是無法捕獲字段唯一約束的錯誤;因此使用formset批量添加數(shù)據(jù)時最好使用第二中方式,手動捕獲唯一約束錯誤信息并交給formset送到前端頁面顯示。

models.Permission.objects.create(**row)
obj = models.Permission(**row) | obj.save()

唯一約束錯誤信息捕獲的過程,需要使用 obj.validate_unique() 判斷該對象是否滿足唯一約束,如果不滿足則通過異常捕獲操作,捕獲異常信息。通過 formset.errors[i].update(e) 把錯誤信息放入formset中送到前端頁面顯示。之所以這樣做,是因為通過forms組件的驗證時無法捕獲唯一約束的錯誤。因此這里通過手動收集錯誤信息并放入forset中。

此外,如果前端頁面渲染的表單沒有填寫數(shù)據(jù),直接提交是不會報錯的。 formset默認(rèn)只要不改動字段就不會對該行數(shù)據(jù)做驗證。只要填寫一個字段,該行數(shù)據(jù)則會做表單驗證 。

# 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中沒有錯誤信息,則講用戶提交的數(shù)據(jù)獲取到。
    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() # 檢查當(dāng)前對象在數(shù)據(jù)庫是否存在唯一的異常。
        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})

前端模板通過兩層循環(huán):第一層循環(huán)formset得到每一個form,第二層循環(huán)form得到每一個字段。與forms組件使用一樣,需要手動添加form表單和input提交數(shù)按鈕及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>標(biāo)題</th>
      <th>URL</th>
      <th>NAME</th>
      <th>菜單</th>
      <th>父權(quán)限</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>

批量編輯

批量編輯和批量增加大體是一致的,但是存在不同的使用區(qū)別。實例化formset對象時默認(rèn)extra=1,需要手動修改為extra=0;GET請求,頁面需要顯示默認(rèn)值,通過參數(shù)initial賦值列表內(nèi)部嵌套字典的數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)。 且需要傳遞每行數(shù)據(jù)的id,告訴formset需要修改的數(shù)據(jù)id 。此時使用的forms類相比批量添加使用的類多一個id字段, id = forms.IntegerField( widget=forms.HiddenInput()) ,默認(rèn)隱藏的字段,前端頁面不顯示。

同理也會遇到唯一約束錯誤,使用循環(huán)和反射為每個字段做數(shù)據(jù)更新賦值,然后再提交數(shù)據(jù)庫保存。

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中沒有錯誤信息,則講用戶提交的數(shù)據(jù)獲取到。
    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})

前端模板循環(huán)顯示每個字段時,要判斷是否是第一個id字段,如果是第一個就直接 {{field}} ,頁面將不會顯示。

<form method="post">
  {% csrf_token %}
  {{ formset.management_form }}
  <table border="1">
    <thead>
    <tr>
      <th>標(biāo)題</th>
      <th>URL</th>
      <th>NAME</th>
      <th>菜單</th>
      <th>父權(quán)限</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>

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Pycharm之快速定位到某行快捷鍵的方法

    Pycharm之快速定位到某行快捷鍵的方法

    今天小編就為大家分享一篇Pycharm之快速定位到某行快捷鍵的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python實現(xiàn)讀取Excel表數(shù)據(jù)并轉(zhuǎn)為JSON格式文件

    Python實現(xiàn)讀取Excel表數(shù)據(jù)并轉(zhuǎn)為JSON格式文件

    這篇文章主要為大家詳細(xì)介紹了Python如何使用pandas庫讀取Excel表并將其轉(zhuǎn)為JSON格式文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考下
    2025-04-04
  • Python中Random和Math模塊學(xué)習(xí)筆記

    Python中Random和Math模塊學(xué)習(xí)筆記

    這篇文章主要介紹了Python中Random和Math模塊學(xué)習(xí)筆記,本文講解了math模塊的數(shù)學(xué)常量、常用簡單函數(shù)、三角函數(shù)等,講解了random模塊的常用函數(shù)、隨機挑選和排序等內(nèi)容,需要的朋友可以參考下
    2015-05-05
  • Python實現(xiàn)從線程獲取返回值

    Python實現(xiàn)從線程獲取返回值

    本文介紹了Python中線程的概念、創(chuàng)建線程的方法和在線程中獲取函數(shù)返回值的技巧,線程作為進程中的執(zhí)行單元,可以實現(xiàn)程序的并發(fā)運行,文章通過示例代碼展示了如何在Python中使用Thread類創(chuàng)建線程,并講解了在線程中傳遞參數(shù)和獲取返回值的方法
    2024-09-09
  • 解決keras,val_categorical_accuracy:,0.0000e+00問題

    解決keras,val_categorical_accuracy:,0.0000e+00問題

    這篇文章主要介紹了解決keras,val_categorical_accuracy:,0.0000e+00問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 淺談Django QuerySet對象(模型.objects)的常用方法

    淺談Django QuerySet對象(模型.objects)的常用方法

    這篇文章主要介紹了淺談Django QuerySet對象(模型.objects)的常用方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Python虛擬環(huán)境與Conda的使用方式

    Python虛擬環(huán)境與Conda的使用方式

    本文將詳細(xì)介紹 Python 虛擬環(huán)境的概念、Conda 的使用以及一些常用命令,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 詳解Python中 __get__和__getattr__和__getattribute__的區(qū)別

    詳解Python中 __get__和__getattr__和__getattribute__的區(qū)別

    __get__、__getattr__、__getattribute都是訪問屬性的方法,但作用不太相同,這里我們就來詳解Python中 __get__和__getattr__和__getattribute__的區(qū)別:
    2016-06-06
  • 手把手教你實現(xiàn)Python重試超時裝飾器

    手把手教你實現(xiàn)Python重試超時裝飾器

    這篇文章主要為大家介紹了實現(xiàn)Python重試超時裝飾器教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2023-05-05
  • python初步實現(xiàn)word2vec操作

    python初步實現(xiàn)word2vec操作

    這篇文章主要介紹了python初步實現(xiàn)word2vec操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06

最新評論

武平县| 永州市| 汪清县| 平原县| 赤城县| 嘉鱼县| 临洮县| 黔西县| 凤冈县| 巴里| 大名县| 泾阳县| 丹江口市| 墨脱县| 运城市| 新竹县| 绿春县| 昭通市| 道孚县| 潢川县| 乌拉特中旗| 宁津县| 潞城市| 彰化市| 孝感市| 本溪市| 南江县| 绥滨县| 仲巴县| 通榆县| 临武县| 高尔夫| 天等县| 德令哈市| 英吉沙县| 松潘县| 昌吉市| 菏泽市| 会泽县| 靖边县| 榆树市|