内联表单集只保存最后一个表单

Posted

技术标签:

【中文标题】内联表单集只保存最后一个表单【英文标题】:inline formset only save the last form 【发布时间】:2020-09-26 21:00:30 【问题描述】:

我尝试了很多方法并搜索了很多(谷歌搜索)但没有人为我工作。每当我保存我的 inlineformset 时,它只会保存最后一个表单, 我的模型.py

class Book(models.Model):
   book = models.CharField(max_length=20,unique=True)
   author = models.ForeignKey(Author,on_delete=models.CASCADE)

class Author(models.Model):
   author = models.CharField(max_length=30,unique=True)
   count = models.IntegerField()

这是我的forms.py

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ['author','count']
class BookForm(ModelForm):
    class Meta:
        model = Book
        fields = ['book']
InlineFormset_Author = inlineformset_factory(Author,Book,form=BookForm,extra=1)

这是我的看法

class CreateBookView(LoginRequiredMixin,SuccessMessageMixin,CreateView):
model = Author
form_class = AuthorForm
def get_context_data(self,*args,**kwargs):
    context = super(CreateBookView,self).get_context_data(*args,**kwargs)
    if self.request.POST:
        context['book'] = InlineFormset_Author(self.request.POST)
    context['book'] = InlineFormset_Author()
    return context
def form_valid(self,form):
    context = self.get_context_data()
    context = context['book']
    with transaction.atomic():
        self.object = form.save()
        if context.is_valid():
            context.instance = self.object
            context.save()
    return super(CreateBookView,self).form_valid(form)

这是我的模板

<form method="POST">% csrf_token %
    book.management_form
    form.author | add_class:'form-control col-12 col-sm-10 mx-auto'
    form.count | add_class:'form-control col-12 col-sm-10 mx-auto' | attr:'id:count'
    <button class="col-4 mx-auto  shadow-lg border-right border-left">insert</button>
    <div id="BOOK" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="my-modal-title" aria-hidden="true">

  <div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header">
  <h5 class="modal-title" id="my-modal-title">BOOK</h5>
  <p class="close" data-dismiss="modal" aria-label="Close">
 <div class="modal-body">
 <button type="submit" class="btn btn-success">save</button></dic>
 </div>
 <div class='modal-footer'></form>
<script>
$(document).ready(function()
$('#BOOKBTN').on('click',function () 
let allValue=[];
let numberOfInput=$('#count').val();
let allContent='';
let justforName=0;
let numOfContent=$('.modal-body input').length;
for(let j=0;j<numOfContent;j++)
justforName=j+1;

allValue.push($('input[name="BOOK'+justforName+'"').val());


if(numOfContent!=numberOfInput)
for(let i=0;i<numberOfInput;i++)
justforName=i+1;
% for i in book.forms %
  allContent+='i.book';
  % endfor %

$('.modal-body').html(allContent);

for(let j=0;j<allValue.length;j++)
justforName=j+1;

$('input[name="BOOK'+justforName+'"').val(allValue[j])
))
</script>

我使用小部件调整来为我的输入字段提供类和 ID 我错过了什么吗?或者我可能做错了什么?! 我已经准备好付钱让它工作了 感谢您的任何建议

【问题讨论】:

我也有同样的问题,django只保存extra参数中指定的表单数量。在你的情况下 1. 你弄清楚了吗? 【参考方案1】:

自从我在 Django 上做任何工作以来已经有好几年了,但我会尝试为您的代码添加注释并添加我的想法。

def form_valid(self,form):
    context = self.get_context_data() # This line looks fine
    context = context['book'] # You are overwriting your context here, call this 
    with transaction.atomic():
        self.object = form.save() # Your have a save here and one further down, this is also setting self object which may be incorrect.
        if context.is_valid():
            context.instance = self.object
            context.save()
    return super(CreateBookView,self).form_valid(form)

就像我说的,我已经好几年没有做过任何 Django 了,所以我只是参考了一些来自 https://github.com/timhughes/django-cbv-inline-formset/blob/master/music/views.py#L26 的旧代码(可能已经过时),我将用 cmets 进行注释。

def form_valid(self, form):
    context = self.get_context_data(form=form)  # Get the context data for the form in question.
    formset = context['track_formset']  # Extract the formset out of the context.
    if formset.is_valid():  # Validate the formset is valid
        response = super().form_valid(form)  # Call the parent class's form_valid.
        formset.instance = self.object  # Set the formsets type (instance of self.object) so that django knows how to save it.
        formset.save()  # Save the formset here
        return response  # Send a response to the user
    else:
        return super().form_invalid(form) # Send a response to the user with invalid form information.

【讨论】:

感谢您的回复,但在我的情况下,问题出在模板内,因为每当我使用自定义的脆皮表单和 jquery.formset.js 时它都会起作用,但我想构建自己的表单,并且仍然保存最后一个表单

以上是关于内联表单集只保存最后一个表单的主要内容,如果未能解决你的问题,请参考以下文章

Django 中的内联表单验证

Django:使用 Jquery 的动态表单集仅保存第一个表单集实例

如何在 Django 的表单中拥有嵌套的内联表单集?

带有清晰表单的内联表单集 - 仅显示一次标签

Django:如何显示内联表单集中每个模型对象的表单错误

如果引发 ValidationError,删除链接会在 Django 管理内联表单集中消失