[英]Django adding item to many-to-many relationships
I'm new to django thus the question. 我是django的新手,因此是个问题。 I've the following Feed object and an User object which have a many-to-many relationship
我有以下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)
The two are related using the Bookmark object. 两者通过Bookmark对象关联。
class Bookmark(Base):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
feed = models.ForeignKey(Feed, on_delete=models.CASCADE, null=True)
My question is, 我的问题是
How do I add a bookmark(or rather feed) to the user? 如何为用户添加书签(或供稿)?
How do I fetch all the feeds the User has bookmarked? 如何获取用户已添加书签的所有供稿?
Any help appreciated. 任何帮助表示赞赏。
This is a good example for your problem 这是解决您的问题的好例子
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)
For this models, if you want to add memberships, you do this: 对于此模型,如果要添加成员资格,请执行以下操作:
>>> 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>]>
Unlike normal many-to-many fields, you can't use add(), create(), or set() to create relationships: 与普通的多对多字段不同,您不能使用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])
You can see this better in Django Docs 您可以在Django Docs中更好地看到这一点
Well, let's start from the beginning. 好吧,让我们从头开始。
As you probably know, when you generate M2M rels with Django, you use the ManyToManyField
. 如您所知,当您使用Django生成M2M关系时,您将使用
ManyToManyField
。 If you do not care about M2M table details, Django will manage it for you. 如果您不关心M2M表的详细信息,Django将为您管理它。 If you want to specify the intermediary table you can use
ManyToManyField.through
. 如果要指定中间表,则可以使用
ManyToManyField.through
。 Exactly as you did. 确实和您一样。 I'm going to semplify your model for explanation purposes.
为了说明的目的,我将简化您的模型。 Something like this:
像这样:
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)
Let's start Django interactive shell. 让我们开始Django交互式shell。 I assume you have an empty database.
我假设您有一个空数据库。
$ django manage.py shell
First of all import your models 首先导入模型
>>> from yourAppName.models import *
Now, create some data: 现在,创建一些数据:
>>> 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>]>
- How do I add a bookmark (or rather feed) to the user?
如何为用户添加书签(或供稿)?
In this case, you cannot use Feed.reader.add(u1)
, you have to use the Bookmark
's Manager since you specified that's your intermediary model. 在这种情况下,您不能使用
Feed.reader.add(u1)
,因为您指定的是中间模型,所以必须使用Bookmark
的Manager。
>>> b1 = Bookmark(user=u1, feed = f1) # add Feed f1 to User u1
>>> b1.save() # save into database
We can also add another bookmark: 我们还可以添加另一个书签:
>>> 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
You are done! 大功告成! Now, we can check if everything is fine.
现在,我们可以检查一切是否正常。
>>> 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'
- How do I fetch all the feeds the User has bookmarked?
如何获取用户已添加书签的所有供稿?
You can simply leverage the Feed.reader
field. 您可以简单地利用
Feed.reader
字段。 Eg, 例如,
>>> for f in Feed.objects.filter(reader = u1):
... print(f.headline)
...
How to use M2M in Django
Fetching data in Django like a pro!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.