【问题标题】:How to save multiple objects in Django models at once如何一次在 Django 模型中保存多个对象
【发布时间】:2021-05-30 20:33:39
【问题描述】:

我要做的是在 Django 模型中的 Actor 表中保存多个抓取的数据(演员名称)。

到目前为止,我已经编写了下面的 for 循环来实现这个目标,但它只保存了最后一个对象。

class Actor(models.Model):
    name = models.CharField(max_length=50)
    url = models.URLField()

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        i = 0
        for num in range(5):
            title, year, actor_list = scraper(self.url)
            self.name = actor_list[i]
            super().save(*args, **kwargs)
            i += 1

我从表单中的用户那里获取 URL,然后保存表单并将其发送到我的模型,然后开始抓取。

我在 scraper() 函数中抓取 5 个演员名称并将它们附加到 actor_list。

但是当我尝试在保存功能下保存actor_list时,它只保存了我认为会覆盖之前保存的对象的第5个actor。

我的 for 循环有问题吗?还是我应该为此彻底改变我的方法?

我还希望使用 Actor.objects.get_or_create() 来保存对象以跳过已经存在的对象,但我不知道如何以及在哪里。

如果有人可以帮助我,我将不胜感激。

【问题讨论】:

    标签: python django


    【解决方案1】:

    是的,您应该使用完全不同的方法。模型只是数据库表的代码表示。

    您还在同一个 url 上执行相同的抓取 5 次,但这是另一点。

    不应该在模型中进行scraping和创建多个actor。请记住,模型被实例化为一个参与者对象(参与者表中的一条记录),因此每次执行 super().save() 时,它都会覆盖相同的记录。

    标准方法是在您用于打印表单的视图中执行此操作,并将该表单提交到其自己的 URL(即表单 action 应指向您用于打印它的同一视图)。

    类似这样的:

    forms.py

    from django import forms
    
    class MyForm(forms.Form):
        url = forms.CharField(label='Your name', max_length=255)
    

    views.py

    from my_app.forms import MyForm
    from my_app.models import Actor
    from django.shortcuts import render
    
    def my_view(request):
        if request.method == "POST":
            form = MyForm(request.POST)
            if form.is_valid():
                title, year, actor_list = scraper(form.cleaned_data['url'])
                for actor in actor_list:
                    # Here you are creating new instances of Actor (new records) 
                    # at each iteration, unless they already exist.
                    Actor.objects.get_or_create(name=actor)
        else:
            form = MyForm()
        return render(request, 'your_template.html', {'form': form})
    

    【讨论】:

    • 您的代码运行良好。也非常感谢您的解释。我是 Django 新手,我完全理解这里的概念。 @MarcCompte
    • 你写了一个很好的问题,这总是更容易得到一个好的答案。很高兴我可以帮助您解决错误,如果您将来学到一些东西,效果会更好。
    【解决方案2】:

    save() 方法作用于单个 Actor 对象。尝试在那里保存多个演员是错误的。

    在视图中执行此操作:

    title, year, actor_list = scraper(self.url)
    for i in range(5):
        actor = Actor()
        actor.name = actor_list[i]
        actor.save()
    

    并删除模型中的save()方法

    【讨论】:

      猜你喜欢
      • 2021-01-10
      • 2022-10-14
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多