【问题标题】:How to get or create object in another model while updating some model?更新某个模型时如何在另一个模型中获取或创建对象?
【发布时间】:2020-06-28 04:32:33
【问题描述】:

我有一个 select2 选项可以在我的表单中选择记者。用户随机将记者姓名放入新闻创建表单中,并在保存表单的同时创建记者对象并将这些对象分配到新闻记者(多对多)字段中。这在创建对象时工作正常

更新时遇到了一些问题。在更新表格中会有新闻中已经分配的记者。用户可以添加记者,也可以从表格中删除记者。在这里,如果用户在表单中添加新的记者,那么我想创建记者对象并在多对多字段中分配记者对象,因此如果用户删除了一些记者。 但是这段代码会创建记者对象,即使它已经在 News 对象中创建和分配。

我想检查记者是否已经在新闻中,然后我不想在记者模型中创建对象。如果只有用户添加新记者,那么我想在记者模型中创建记者对象,然后在新闻中分配这个对象。我该怎么做?

class UpdateNews(View):
    template_name = 'update_news.html'
    categories = NewsCategory.objects.order_by('-created')

    def get(self, request, **kwargs):
        news = get_object_or_404(News, pk=kwargs['pk'])
        form = CreateNewsForm(instance=news)
        return render(request, self.template_name,
                      {'form': form, 'news': news, 'categories': self.categories})

    def post(self, request, *args, **kwargs):
        target = get_object_or_404(News, pk=kwargs['pk'])
        form = CreateNewsForm(request.POST, instance=news)
        if form.is_valid():
            news = form.save()
            reporters = request.POST.getlist('reporters')
            reporters_pk = [Reporter.objects.create(name=reporter).pk for reporter in reporters]
            news.reporters.set(reporters_pk)
            return redirect('list_news')
        return render(request, self.template_name,
                      {'form': form, 'news': news, 'categories': self.categories})

型号

class Reporter(models.Model):
   name = models.CharField(max_length=255)
   created = models.DateTimeField(auto_now_add=True)

class News(models.Model):
    title = models.CharField(max_length=255)
    reporters = models.ManyToManyField(Reporter, related_name='reporters')

我曾尝试使用get_or_create 方法,但它会引发错误

reporters_pk = [Reporter.objects.get_or_create(name=reporter).pk for reporter in reporters]

错误

'tuple' object has no attribute 'pk'

【问题讨论】:

    标签: django django-models django-views


    【解决方案1】:

    get_or_create 返回一个元组

    instance, created = get_or_create(...)
    

    如果你想访问记者的pk,请先尝试获取实例

    reporters_pk = [Reporter.objects.get_or_create(name=reporter)[0].pk for reporter in reporters]
    

    【讨论】:

      【解决方案2】:

      最简单和最好的方法是使用 Django 内置的get_or_create 方法。在您的情况下,这将给出:

          def post(self, request, *args, **kwargs):
              target = get_object_or_404(News, pk=kwargs['pk'])
              form = CreateNewsForm(request.POST, instance=news)
              if form.is_valid():
                  news = form.save()            
                  reporters = request.POST.getlist('reporters')
                  # magic here 'get_or_create'
                  reporters_pk = [Reporter.objects.get_or_create(name=reporter).pk for reporter in reporters]
                  news.reporters.set(reporters_pk)
                  return redirect('list_news')
              return render(request, self.template_name,
                            {'form': form, 'news': news, 'categories': self.categories})
      

      所以对于每个返回True 标识符name=reporter 的报告者来说,它会从数据库中获取现有对象,否则它会创建一个新对象。这样您就可以避免以多个条目结束。

      所以基本上你已经用标题指出了正确的方向,或者你没有正确描述你的问题;)

      【讨论】:

      • 我试过这个它会抛出一个错误。AttributeError: 'tuple' object has no attribute 'pk'
      猜你喜欢
      • 2011-07-01
      • 1970-01-01
      • 2017-05-19
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-11
      • 2015-10-20
      相关资源
      最近更新 更多