Django与用户默认身份验证模型和其他模型的关系

2024-04-26 06:53:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个web应用程序,用户可以订阅系统内部可以看到的不同系列的文本。我想在UserSeriesText之间创建一个关系,这样我就可以在视图中抓取当前登录的用户,并在仪表板模板中返回他的所有订阅。 用户可以订阅任意数量的系列

我正在使用来自django.contrib.auth.models的默认User模型,我不确定如何创建这种关系

我读了很多书,我认为这里正确的用法应该是Many-to-many(正确吗?),所以我尝试了这个,使用了一个名为Subscriptions的透视表/模型:

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()

但这似乎不起作用,我甚至在尝试使用User.objects.get(pk=1)时也出现了错误,我真的不知道为什么

我真的很困惑,如果我需要将关系放在两个方面,比如在SeriesText模型上创建models.ManyToMany和在扩展的User模型上创建models.ManyToMany(我甚至不知道是否真的是这样做的)。我甚至不确定这是否是使用默认auth用户模型建立关系的正确方法

为了以后能够搜索订阅了一个系列的所有用户,我认为models.ManyToMany也应该在SeriesText模型上,这也是正确的吗

有人能帮助我了解我是否使用了正确的关系(多对多),以及如何建立这种关系吗?提前谢谢,我对Django很陌生,我在这里遇到麻烦了


Tags: django用户模型selfauthid关系models
1条回答
网友
1楼 · 发布于 2024-04-26 06:53:57

您只需要在SeriesText上添加一个m2m字段。从根本上说,多对多字段连接到哪个模型并不重要(数据库看起来是一样的,如果不一样,数据访问也会相似)。根据我的经验,如果您不必弄乱Django用户模型,那就更好了:

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

要了解其工作原理,请首先添加一些数据:

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)

然后,为了获取SerieText的所有订阅者(我在这里从数据库中获取对象,以表明它不是上面最后两行的人工制品-数据库中的数据已更改):

>>> 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>]

要获取用户的所有订阅(我们声明,在多对多字段中,从用户到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>]

如果我们没有声明相关的_名称,我们将不得不使用默认名称:

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

这也不好读

相关问题 更多 >