初始化表单集

编程入门 行业动态 更新时间:2024-10-26 15:26:19
本文介绍了初始化表单集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有两个通过多方关系连接的模型,我试图使用 formset 创建一个动态表单。我能够保存表单,但是当我尝试编辑保存的实例时出现问题,我不知道如何正确地将实例传递给表单集,以便它在表单中显示实例数据以供编辑

I have two models connected by manytomany relationship and I am trying to use formset to create a dynamic form. I am able to save the form but the problem arise when I am trying to edit the saved instance, I don't know how to properly pass the instance to the formset such that it shows the instance data in form for editing

以下是详细信息:

Models.py

Models.py

class Player(models.Model): pname = models.CharField(max_length=50) hscore = models.IntegerField() age = models.IntegerField() def __str__(self): return self.pname class Team(models.Model): tname = models.CharField(max_length=100) player= models.ManyToManyField(Player) def __str__(self): return self.tname

Forms.py

class PlayerForm(forms.ModelForm): class Meta: model = Player fields = '__all__' PlayerFormset= formset_factory(PlayerForm) class TeamForm(forms.ModelForm): player= PlayerFormset() class Meta: model = Team fields = '__all__' exclude = ["player"]

Views.py

def team(request): if request.POST: form = TeamForm(request.POST) form.player_instances = PlayerFormset(request.POST) if form.is_valid(): team= Team() team.tname= form.cleaned_data['tname'] team.save() if form.player_instances.cleaned_data is not None: for item in form.player_instances.cleaned_data: player = Player() player.pname= item['pname'] player.hscore= item['hscore'] player.age= item['age'] player.save() team.player.add(player) team.save() else: form = TeamForm() return render(request, 'packsapp/employee/new.html', {'form':form}) def updateTeam(request,pk): team = Team.objects.get(id=pk) form = TeamForm(instance=team) // something here to initialize the formset ?? if request.method == "POST": form = TeamForm(request.POST, instance=team) if form.is_valid(): form.save() context = {'form': form} return render(request, 'packsapp/employee/new.html', context)

Html

<html> <head> <title>gffdfdf</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="maxcdn.bootstrapcdn/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="ajax.googleapis/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="/static/jquery.formset.js"></script> <script src="maxcdn.bootstrapcdn/bootstrap/3.3.7/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <form id="myForm" action="" method="post" class=""> {% csrf_token %} <h2> Team</h2> {% for field in form %} {{ field.errors }} {{ field.label_tag }} {{ field }} {% endfor %} {{ form.player.management_form }} <h3> Product Instance(s)</h3> <table id="table-product" class="table"> <thead> <tr> <th>player name</th> <th>highest score</th> <th>age</th> </tr> </thead> {% for player in form.player %} <tbody class="player-instances"> <tr> <td>{{ player.pname }}</td> <td>{{ player.hscore }}</td> <td>{{ player.age }}</td> <td><input id="input_add" type="button" name="add" value=" Add More " class="tr_clone_add btn data_input"></td> </tr> </tbody> {% endfor %} </table> <button type="submit" class="btn btn-primary">save</button> </form> </div> <script> var i = 1; $("#input_add").click(function () { $("tbody tr:first").clone().find(".data_input").each(function () { if ($(this).attr('class') == 'tr_clone_add btn data_input') { $(this).attr({ 'id': function (_, id) { return "remove_button" }, 'name': function (_, name) { return "name_remove" + i }, 'value': 'Remove' }).on("click", function () { var a = $(this).parent(); var b = a.parent(); i = i - 1 $('#id_form-TOTAL_FORMS').val(i); b.remove(); $('.player-instances tr').each(function (index, value) { $(this).find('.data_input').each(function () { $(this).attr({ 'id': function (_, id) { console.log("id", id) var idData = id; var splitV = String(idData).split('-'); var fData = splitV[0]; var tData = splitV[2]; return fData + "-" + index + "-" + tData }, 'name': function (_, name) { console.log("name", name) var nameData = name; var splitV = String(nameData).split('-'); var fData = splitV[0]; var tData = splitV[2]; return fData + "-" + index + "-" + tData } }); }) }) }) } else { $(this).attr({ 'id': function (_, id) { console.log("id", id) var idData = id; var splitV = String(idData).split('-'); var fData = splitV[0]; var tData = splitV[2]; return fData + "-" + i + "-" + tData }, 'name': function (_, name) { console.log("name", name) var nameData = name; var splitV = String(nameData).split('-'); var fData = splitV[0]; var tData = splitV[2]; return fData + "-" + i + "-" + tData } }); } }).end().appendTo("tbody"); $('#id_form-TOTAL_FORMS').val(1 + i); $("tbody tr:last :input").each(function () { $(this).attr({ 'id': function (_, id) { return id.replace(/\d/g, i) }, 'name': function (_, name) { return name.replace(/\d/g, i) }, }) }) i++; }); </script> </body> </html>

更新:

使用 modelformset_factory 直接在视图中:

def post(request): tform = TeamForm() pform = modelformset_factory(Player, form=PlayerForm, extra = 1) pform = pform(request.POST or None, queryset = Player.objects.filter(id__isnull = True)) if request.method == 'POST': t = Team() tform = TeamForm(request.POST, instance=t) if tform.is_valid() and pform.is_valid(): tform.save() instances = pform.save(commit=False) for i in instances: player = Player() player.pname = i.pname player.hscore = i.age player.age = i.hscore player.save() t.player.add(player) t.save() return redirect('/exams/dashboard/') else: print('invalid data') return render(request, 'team/team_create.html', {'exform': tform, 'exformset': pform}) def update(request, pk = None): team = Team.objects.get(id = pk) tform = TeamForm(instance = team) pform = modelformset_factory(Player, form=PlayerForm, extra=0) print("players", Player.objects.filter(team=team)) pform = pform(request.POST or None, queryset=Player.objects.filter(team=team)) if request.method == 'POST': tform = TeamForm(request.POST, instance=team) print("tform ", tform) print("pform ", pform) if tform.is_valid() and pform.is_valid(): tform.save() instances = pform.save(commit=False) for i in instances: player = Player() player.pname = i.pname player.hscore = i.age player.age = i.hscore player.save() t.player.add(player) t.save() return redirect('/exams/dashboard/') else: print('invalid data') return render(request, 'team/team_create.html', {'exform': tform, 'exformset': pform})

推荐答案

TeamForm必须设置PlayerFormset的queryset。 下面显示了如何。

The TeamForm has to set the queryset of the PlayerFormset. The following shows how.

class TeamForm(forms.ModelForm): player= PlayerFormset() class Meta: model = Team fields = '__all__' exclude = ["player"] def __init__(self,*args, **kwargs): super(TeamForm,self).__init__(*args,**kwargs) self.player = PlayerFormSet(queryset=Players.objects.filter(team=self.instance)

文档中的信息: docs.djangoproject/en/2.2/topics/forms/modelforms/#changing-the-queryset

也许也值得一看: stackoverflow/a/34323401/ 13168118

编辑:

您的 PlayerFormset 应该使用 modelformset_factory 创建,例如:

your PlayerFormset should be created with a modelformset_factory like:

PlayerFormset = modelformset_factory(Player, form=PlayerForm)

modelformset文档: docs.djangoproject/en/2.2/ref/forms/models/#modelformset-factory

modelformset documentation: docs.djangoproject/en/2.2/ref/forms/models/#modelformset-factory

更多推荐

初始化表单集

本文发布于:2023-11-04 01:22:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1556561.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:表单   初始化

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!