Django将项目添加到多对多关系中

时间:2018-04-11 20:48:12

标签: python django python-3.x

我对django这个问题很新。我有以下Feed对象和具有多对多关系的User对象

class Feed(Base):
    headline = models.CharField(max_length=255)
    link = models.CharField(max_length=255)
    summary = models.TextField()
    reader = models.ManyToManyField(User, through='Bookmark')

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True, max_length=255)
    mobile = PhoneNumberField(null=True)
    username = models.CharField(null=True, unique=True, max_length=255)
    full_name = models.CharField(max_length=255, blank=True, null=True)

这两个是使用书签对象相关的。

class Bookmark(Base):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    feed = models.ForeignKey(Feed, on_delete=models.CASCADE, null=True)

我的问题是,

  1. 如何向用户添加书签(或更确切地说是Feed)?

  2. 如何获取用户已添加书签的所有Feed?

  3. 任何帮助表示感谢。

2 个答案:

答案 0 :(得分:2)

这是您的问题的一个很好的例子

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

对于此模型,如果要添加成员资格,请执行以下操作:

>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
...     date_joined=date(1962, 8, 16),
...     invite_reason="Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>]>
>>> ringo.group_set.all()
<QuerySet [<Group: The Beatles>]>
>>> m2 = Membership.objects.create(person=paul, group=beatles,
...     date_joined=date(1960, 8, 1),
...     invite_reason="Wanted to form a band.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>

与普通的多对多字段不同,您不能使用add(),create()或set()来创建关系:

>>> # The following statements will not work
>>> beatles.members.add(john)
>>> beatles.members.create(name="George Harrison")
>>> beatles.members.set([john, paul, ringo, george])

您可以在Django Docs

中更好地看到这一点

答案 1 :(得分:1)

好吧,让我们从头开始吧。

您可能知道,当您使用Django生成M2M rels时,您使用ManyToManyField。如果你不关心M2M表的细节,Django会为你管理它。如果要指定中间表,可以使用ManyToManyField.through。正如你所做的那样。为了解释的目的,我将简化您的模型。像这样:

class User(models.Model):
    username = models.CharField(null=True, unique=True, max_length=255)

class Feed(models.Model):
    headline = models.CharField(max_length=255)
    reader = models.ManyToManyField(User, through='Bookmark')

class Bookmark(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    feed = models.ForeignKey(Feed, on_delete=models.CASCADE, null=True)

让我们开始Django交互式shell。我假设你有一个空的数据库。

$ django manage.py shell

首先导入你的模型

>>> from yourAppName.models import * 

现在,创建一些数据:

>>> from bat.models import *
>>> u1 = User(username = 'foo')
>>> u1.save()
>>> u2 = User(username = 'bar')
>>> u2.save()
>>> User.objects.all() # get Users u1 and u2
<QuerySet [<User: User object>, <User: User object>]>
>>> f1 = Feed(headline = 'How to use M2M in Django')
>>> f1.save()
>>> Feed.objects.all() # get Feed f1
<QuerySet [<Feed: Feed object>]>
  
      
  1. 如何向用户添加书签(或更确切地说是Feed)?
  2.   

在这种情况下,您无法使用Feed.reader.add(u1),因为您指定了中间模型,因此您必须使用Bookmark的经理。

>>> b1 = Bookmark(user=u1, feed = f1) # add Feed f1 to User u1
>>> b1.save() # save into database

我们还可以添加另一个书签:

>>> f2 = Feed(headline = 'Fetching data in Django like a pro!')
>>> f2.save()
>>> b2 = Bookmark(user=u1, feed = f2) # add Feed f2 to User u1
>>> b2.save() # save into database

你完成了!现在,我们可以检查一切是否正常。

>>> brandNewBookMark = Bookmark.objects.all()[0] # get the first bookmark
>>> print(brandNewBookMark.user.username) # it's Foo!
foo
>>> print(brandNewBookMark.feed.headline) # Foo subscribed to f1!
u'How to use M2M in Django'
  
      
  1. 如何获取用户已添加书签的所有Feed?
  2.   

您可以简单地利用Feed.reader字段。如,

>>> for f in Feed.objects.filter(reader = u1):
...     print(f.headline)
...    
How to use M2M in Django
Fetching data in Django like a pro!

那就是它!更多信息here