【问题标题】:Many to many relation. ORM Django多对多关系。 ORM Django
【发布时间】:2012-09-18 14:05:27
【问题描述】:
class Toy(models.Model):
    name = models.CharField(max_length=20)
    desc = models.TextField()

class Box(models.Model):
    name = models.CharField(max_length=20)
    proprietor = models.ForeignKey(User, related_name='User_Box')
    toys = models.ManyToManyField(Toy, blank=True)

如何创建一个将玩具添加到盒子的视图?

def add_this_toy_to_box(request, toy_id):

【问题讨论】:

  • 你想让视图做什么?你试过什么?
  • 我尝试将玩具模型中的对象添加到盒子模型中。例如:Toy - name = "Ponny", desc = "pink ponny"。我想将此数据添加到 Box 模型中:Box - name = "Box1", proprietor = "user3", toys="Ponny" 可能还有其他玩具。
  • 玩具可以同时属于其他盒子还是一次只属于一个盒子?
  • 玩具可以属于其他盒子

标签: python django django-orm


【解决方案1】:

你可以使用Django的RelatedManager:

“相关管理器”是在一对多或多对多相关上下文中使用的管理器。这发生在两种情况下:

ForeignKey 关系的“另一面”。那就是:

class Reporter(models.Model):
    ...

class Article(models.Model):
    reporter = models.ForeignKey(Reporter)

在上面的例子中,下面的方法将在经理reporter.article_set上可用。

ManyToManyField 关系的双方:

class Topping(models.Model):
    ...

class Pizza(models.Model):
    toppings = models.ManyToManyField(Topping)

在本例中,topping.pizza_setpizza.toppings 都可以使用以下方法。

这些相关的管理器有一些额外的方法:

  1. 要创建一个新对象,将其保存并放入相关的对象集中。返回新创建的对象: 创建(**kwargs)

    >>> b = Toy.objects.get(id=1)
    >>> e = b.box_set.create(
    ...     name='Hi',
    ... )
    
    # No need to call e.save() at this point -- it's already been saved.
    
    # OR:
    
    >>> b = Toy.objects.get(id=1)
    >>> e = Box(
    ...     toy=b,
    ...     name='Hi',
    ... )
    >>> e.save(force_insert=True)
    
  2. 将模型对象添加到相关对象集:

    add(obj1[, obj2, ...])
    

    例子:

    >>> t = Toy.objects.get(id=1)
    >>> b = Box.objects.get(id=234)
    >>> t.box_set.add(b) # Associates Box b with Toy t.
    
  3. To 从相关对象集中移除指定的模型对象:

    remove(obj1[, obj2, ...])
    
    >>> b = Toy.objects.get(id=1)
    >>> e = Box.objects.get(id=234)
    >>> b.box_set.remove(e) # Disassociates Entry e from Blog b.
    

    为了防止数据库不一致,该方法只存在于null=True的ForeignKey对象上。如果相关字段不能设置为无 (NULL),则无法从关系中删除对象而不将其添加到另一个对象。上例中,从 b.entry_set() 中去掉 e 就相当于做 e.blog = None,而且由于博客 ForeignKey 没有 null=True,所以这是无效的。

  4. 从相关对象集中删除所有对象: 清除()

    >>> b = Toy.objects.get(id=1)
    >>> b.box_set.clear()
    

    请注意,这不会删除相关对象——它只是解除它们的关联。 与 remove() 一样,clear() 仅适用于 null=True 的 ForeignKeys。


参考:Relevant Django doc on handling related objects

【讨论】:

    【解决方案2】:

    Django 会自动在 ManyToManyFields 上创建反向关系,所以你可以这样做:

    toy = Toy.objects.get(id=toy_id)
    toy.box_set.add(box)
    

    【讨论】:

      猜你喜欢
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 2021-06-26
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 2019-09-08
      相关资源
      最近更新 更多