简体   繁体   English

Django 与用户默认身份验证 model 和另一个 Model 的关系

[英]Django relationship with User default auth model and another Model

I'm developing a web application where users can subscribe to different series of texts, that would be seen inside the system.我正在开发一个 web 应用程序,用户可以在其中订阅不同系列的文本,这些文本将在系统内部看到。 I want to create a relationship between the User and the SeriesText , so I can grab the current logged user in the VIEW, and just return all of his subscriptions at the dashboard template.我想在UserSeriesText之间创建关系,这样我就可以在 VIEW 中获取当前登录的用户,然后在仪表板模板中返回他的所有订阅。 An user would be able to subscribe to as many series as he wants.用户将能够订阅任意数量的系列。

I'm using the default User model from django.contrib.auth.models , and I'm not sure how to create this relationship.我正在使用来自django.contrib.auth.models的默认User model ,我不确定如何创建这种关系。

I read a lot and I think the correct usage here would be Many-to-many (is that correct?), so I tried this, using a pivot table/model called Subscriptions :我读了很多,我认为这里的正确用法是Many-to-many (正确吗?),所以我尝试了这个,使用名为Subscriptions的 pivot 表/模型:

from django.contrib.auth.models import User as BaseUserClass

class User(BaseUserClass):
    subscriptions = models.ManyToManyField(SeriesText, through="Subscription")


 class SeriesText(models.Model):
    series_name = models.CharField(max_length=255)
    series_text = models.CharField(max_length=255)
    subbed_users = models.ManyToManyField(User, through="Subscription")


class Subscription(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    series = models.ForeignKey(SeriesText, on_delete=models.CASCADE)

    def subscribe(self, user_id, series_id):
        self.user = user_id
        self.series = series_id
        self.save()

But that didn't seem to work, I got errors even trying to use a User.objects.get(pk=1) , don't really know why.但这似乎不起作用,我什至尝试使用User.objects.get(pk=1)时遇到错误,我真的不知道为什么。

I'm really confused if I need to put the relationship both ways, like created models.ManyToMany on SeriesText model, and on an extended User model (that I don't even know if that's really the way to do it).如果我需要两种方式来放置关系,我真的很困惑,比如在SeriesText model 和扩展User model 上创建的models.ManyToMany (我什至不知道这是否真的是这样做的方法)。 I'm not even sure if that the correct way to make a relationship using the default auth user model.我什至不确定这是否是使用默认身份验证用户 model 建立关系的正确方法。

To be able to later also search for all users subscribed to a series, I think that the models.ManyToMany should also be on the SeriesText model, is that also correct?为了以后也能搜索到所有订阅了一个系列的用户,我认为models.ManyToMany也应该在SeriesText model上,这也正确吗?

Can someone help me understand if I'm using the correct relationship (many-to-many), and how to make this relationship?有人可以帮助我了解我是否使用正确的关系(多对多),以及如何建立这种关系? Thanks in advance, I'm pretty new to Django I'm hitting a wall here.在此先感谢,我对 Django 很陌生,我在这里碰壁了。

You only need to add a m2m field on SeriesText .您只需要在SeriesText上添加一个 m2m 字段。 Fundamentally, it doesn't matter which model a many-to-many field is attached to (the database will look the same and the data access will be similar if not identical).从根本上说,多对多字段附加到哪个 model 并不重要(数据库看起来相同,如果不相同,数据访问也将相似)。 Based on my experience, it's better if you don't have to mess with the Django User model:根据我的经验,最好不要乱用 Django 用户 model:

class SeriesText(models.Model):
    series_name = models.CharField(max_length=255)
    series_text = models.CharField(max_length=255)
    subscribers = models.ManyToManyField(User, related_name='subscriptions')

    def __str__(self):
        return self.series_name

To see how that works, first add some data:要查看它是如何工作的,首先添加一些数据:

s1 = SeriesText.objects.create(series_name='name1', series_text='text1')
s2 = SeriesText.objects.create(series_name='name2', series_text='text2')

u1 = User.objects.create_user('user1')
u2 = User.objects.create_user(username='user2')
u3 = User.objects.create_user(username='user3')
u4 = User.objects.create_user(username='user4')
u5 = User.objects.create_user(username='user5')

s1.subscribers.add(u1, u2, u3)
s2.subscribers.add(u3, u4, u5)

Then to fetch all subscribers for a SeriesText (I'm fetching the objects from the database here to show that it is not an artefact of the last two lines above - data has been changed in the database):然后获取 SeriesText 的所有订阅者(我在这里从数据库中获取对象以表明它不是上面最后两行的人工制品 - 数据库中的数据已更改):

>>> SeriesText.objects.get(series_name='name1').subscribers.all()
[<User: user1>, <User: user2>, <User: user3>]

>>> SeriesText.objects.get(series_name='name2').subscribers.all()
[<User: user3>, <User: user4>, <User: user5>]

to fetch all subscriptions for a user (we declared that the relation from User to SeriesText should be named subscriptions in the many-to-many field):获取用户的所有订阅(我们声明从 User 到 SeriesText 的关系应该在多对多字段中命名为subscriptions ):

>>> User.objects.get(username='user1').subscriptions.all()
[<SeriesText: name1>]
>>> User.objects.get(username='user2').subscriptions.all()
[<SeriesText: name1>]
>>> User.objects.get(username='user3').subscriptions.all()
[<SeriesText: name1>, <SeriesText: name2>]
>>> User.objects.get(username='user4').subscriptions.all()
[<SeriesText: name2>]
>>> User.objects.get(username='user5').subscriptions.all()
[<SeriesText: name2>]

If we hadn't declared the related_name we would have had to use the default:如果我们没有声明related_name,我们将不得不使用默认值:

User.objects.get(username='user1').seriestext_set.all()

which doesn't read as well.这也不好读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM