Django:将对象添加到相关集合而不保存到DB

Django:将对象添加到相关集合而不保存到DB,django,django-models,Django,Django Models,我试图在应用程序中编写一个内部API,而不必将其与数据库耦合 class Product(models.Model): name=models.CharField(max_length=4000) price=models.IntegerField(default=-1) currency=models.CharField(max_length=3, default='INR') class Image(models.Model): # NOTE -- Hav

我试图在应用程序中编写一个内部API,而不必将其与数据库耦合

class Product(models.Model):
    name=models.CharField(max_length=4000)
    price=models.IntegerField(default=-1)
    currency=models.CharField(max_length=3, default='INR')

class Image(models.Model): 
    # NOTE -- Have changed the table name to products_images
    width=models.IntegerField(default=-1)
    height=models.IntegerField(default=-1)
    url=models.URLField(max_length=1000, verify_exists=False)
    product=models.ForeignKey(Product)

def create_product:
    p=Product()
    i=Image(height=100, widght=100, url='http://something/something')
    p.image_set.add(i)
    return p
现在,当我调用create_product()时,Django抛出了一个错误:

IntegrityError: products_images.product_id may not be NULL
但是,如果我在调用p.image_set.add(I)之前调用p.save()&I.save(),它就会工作。是否有任何方法可以将对象添加到相关对象集中,而无需先将两者保存到DB

def create_product():
    product_obj = Product.objects.create(name='Foobar')
    image_obj = Image.objects.create(height=100, widght=100, url='http://something/something', product=product_obj)
    return product_obj
说明: 必须首先创建产品对象,然后将其分配给图像对象,因为此处的id和名称是必填字段

我想知道为什么在第一种情况下,您不需要在DB中输入产品?如果有任何具体的原因,那么我可以建议你做一些变通

编辑:好的!我想我明白了,你不想一开始就把产品分配给图像对象。将product字段创建为null等于true如何

product = models.ForeignKey(Product, null=True)
现在,您的函数变成如下所示:

def create_product():
        image_obj = Image.objects.create(height=100, widght=100, url='http://something/something')
        return image_obj

希望对您有所帮助?

您的问题是,id不是由django设置的,而是由数据库设置的(它在数据库中由一个自动递增的字段表示),因此,在保存之前,没有id。有关这方面的详细信息

我可以想出三种可能的解决办法:

  • 将图像模型的不同字段设置为主键(已记录)
  • 将生产模型的不同字段设置为外键(已记录)
  • 使用django的数据库事务API(有文档记录)

  • 我对@Saurabh Nanda也有同样的问题

    我正在使用Django 1.4.2。当我读到django时,我看到了

    # file django/db/models/fields/related.py
    def get_query_set(self):                                              
       try:                                                              
          return self.instance._prefetched_objects_cache[rel_field.related_query_name()]
       except (AttributeError, KeyError):                                
          db = self._db or router.db_for_read(self.model, instance=self.instance)
          return super(RelatedManager,self).get_query_set().using(db).filter(**self.core_filters)
    
    
    # file django/db/models/query.py 
    qs = getattr(obj, attname).all()                                          
    qs._result_cache = vals                                                   
    # We don't want the individual qs doing prefetch_related now, since we
    # have merged this into the current work.                                 
    qs._prefetch_done = True                                                  
    obj._prefetched_objects_cache[cache_name] = qs
    
    这就是为什么,我们只需要为对象设置属性
    \u prefetched\u objects\u cache

    p = Product()
    image_cached = []
    for i in xrange(100): 
       image=Image(height=100, widght=100, url='http://something/something')
       image_cached.append(image)
    qs = p.images.all()
    qs._result_cache = image_cached
    qs._prefetch_done = True
    p._prefetched_objects_cache = {'images': qs}
    

    谢谢你的回复。但是,由于对象是在函数中创建的,函数是内部API的一部分,因此我不想将它们保存到DB中。在这一点上,对象很有可能处于不完整状态。而且,如果我使用你的建议,我将损害数据库的一致性。如果不与产品关联,则图像不能存在于数据库中。如果我要强制执行此操作,则整个函数调用必须在DB事务块中进行,这样,如果发生错误(在将映像保存到DB后),DB将回滚到一致状态。在我看来,对于一个解耦的API有太多的假设。谢谢!我不知道
    \u预取对象\u缓存
    ,这正是我一直在寻找的。