日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

django批量修改table_django-formset实现数据表的批量操作

發(fā)布時(shí)間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 django批量修改table_django-formset实现数据表的批量操作 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是formset

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

批量添加

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

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

models.Permission.objects.create(**row)

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

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

此外,如果前端頁(yè)面渲染的表單沒(méi)有填寫(xiě)數(shù)據(jù),直接提交是不會(huì)報(bào)錯(cuò)的。formset默認(rèn)只要不改動(dòng)字段就不會(huì)對(duì)該行數(shù)據(jù)做驗(yàn)證。只要填寫(xiě)一個(gè)字段,該行數(shù)據(jù)則會(huì)做表單驗(yàn)證。

# 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中沒(méi)有錯(cuò)誤信息,則講用戶提交的數(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)前對(duì)象在數(shù)據(jù)庫(kù)是否存在唯一的異常。

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})

前端模板通過(guò)兩層循環(huán):第一層循環(huán)formset得到每一個(gè)form,第二層循環(huán)form得到每一個(gè)字段。與forms組件使用一樣,需要手動(dòng)添加form表單和input提交數(shù)按鈕及csrf_token跨域偽造請(qǐng)求。此外,使用formset,還需要增加{{ formset.management_form }} , 使用哪個(gè)formset就增加哪個(gè)formset.management_form.

# multi_add.html

{% csrf_token %}

{{ formset.management_form }}

標(biāo)題URLNAME菜單父權(quán)限

{% for form in formset %}

{% for field in form %}

{{ field }} {{ field.errors.0 }}

{% endfor %}

{% endfor %}

批量編輯

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

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

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中沒(méi)有錯(cuò)誤信息,則講用戶提交的數(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)顯示每個(gè)字段時(shí),要判斷是否是第一個(gè)id字段,如果是第一個(gè)就直接{{field}},頁(yè)面將不會(huì)顯示。

{% csrf_token %}

{{ formset.management_form }}

標(biāo)題URLNAME菜單父權(quán)限

{% for form in formset %}

{% for field in form %}

{% if forloop.first %}

{{ field }}

{% else %}

{{ field }} {{ field.errors.0 }}

{% endif %}

{% endfor %}

{% endfor %}

標(biāo)簽:form,request,django,forms,數(shù)據(jù)表,id,formset,row

來(lái)源: https://www.cnblogs.com/liuxu2019/p/11992573.html

總結(jié)

以上是生活随笔為你收集整理的django批量修改table_django-formset实现数据表的批量操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。