如何重写createView以保存多个数据条目

3 投票
2 回答
706 浏览
提问于 2025-04-18 08:10

我想用CreateView这个类来保存多个数据条目。
举个例子,输入的内容是:

    物品是“苹果、香蕉、胡萝卜”
    地点是“地点1”

我想把它们保存到数据库里,像这样:
    [苹果,地点1]
    [香蕉,地点1]
    [胡萝卜,地点1]

#model.py
class Inventory(models.Model):
    item = models.CharField(max_length=14)
    location = models.CharField(max_length=10)

#forms.py
class InventoryCreateForm(forms.ModelForm):
    item = forms.CharField(widget=forms.Textarea(attrs={'rows': 8,                                                      
                                                       'cols': 14}))
    class Meta:
        model = Inventory

#views.py
class InventoryCreateView(CreateView):
    model = Inventory
    form_class = InventoryCreateForm

谢谢

2 个回答

0

希望这能帮助到其他来到这个页面的人。

这是我所做的:

class TrainingBulkCreateForm(ModelForm):
    # todo: could we make the original user object a multiple choice field instead?
    extra_user = forms.ModelMultipleChoiceField(queryset=User.objects.filter(is_active=True), required=True)

    class Meta(object):
        model = Training
        fields = '__all__'
    def post(self, request, *args, **kwargs):
        result = super().post(request, *args, **kwargs)
        users = request.POST.getlist('extra_user')
        if users:
            # modify request.POST data then re-save the additional users

            for user in users:
                # Need to copy the data because the initial QueryDict is immutable data
                postdata_copy = request.POST.copy()
                postdata_copy['user'] = user
                form2 = TrainingBulkCreateForm(postdata_copy)

                form2.save()

        return result

我有一个叫做 item 的字段(我的字段是 user),它被分成了两个表单字段 - 原始的 item 是一个对象,比如 apple

然后我还有一个叫 extra_user 的第二个表单字段。这个字段可以接受多个对象,比如 [banana, carrots]

在视图中,我调用 super().post(...) 来保存最初的 apple 对象。接着我检查 extra_user 字段,看看是否有多个食物。如果有额外的食物,我会复制不可变的 QueryDict 对象 request.POST,命名为 postdata_copy

然后我修改 postdata_copy,把 apple 替换成 banana。(这基本上就是把 apple 的表单复制一份,改成 banana,然后重新保存这个表单)。接着我们再循环一次,把 apple 替换成 carrots

注意,我的表单对象使用了 ModelMultipleChoiceField 来处理 extra_user 对象。这样比直接输入文本要更可靠。

2

你需要重写“form_valid()”这个方法,它是用在创建视图(createview)里的。

接下来,你需要读取表单中的数据。

def form_valid(self,form):
    self.object = form.save(commit=False)
    foo = self.object.bar #your data is in the object

因为你使用的是文本框,所以你需要把输入到表单中的数据分开,并逐个处理这些值。理想情况下,你会想要一个像这样的列表:['apple', 'banana', 'pear'],然后从这个列表中提取出位置,并把它存储到一个可以后续使用的变量中,叫做location_variable

一旦你得到了想要的表单数据,你就需要创建一个库存模型(Inventory model)。

from foo.models import Inventory #import at the top of your file  

for item is list:
    inventory = Inventory()
    inventory.item = item
    inventory.location = location_variable
    inventory.save()

希望这个回答能对你有所帮助。如果你想了解更多关于基于类的视图的信息,可以访问ccbv,那里列出了每个视图的所有信息。

或者,你也可以查看django的表单文档,寻找更合适的表单使用。

撰写回答