首页 > 解决方案 > 在 Django 中,如何立即将组的创建者添加到该组?

问题描述

我正在 Django 中创建一个“社交”应用程序,用户可以在其中创建组(联盟),其他人可以加入这些组。用户资料联盟通过会员模式连接。我希望这样的组的创建者立即成为它的成员。

我对Django没有经验,其实这是我的第一个项目。但我想这也许可以通过信号来解决?

我的用户个人资料模型:

class Profile(models.Model):
    ...
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    alliances = models.ManyToManyField('Alliance', through='Membership')
    ...

我的联盟模型:

class Alliance(models.Model):
    ...
    name = models.CharField(max_length=10, unique=True)
    members = models.ManyToManyField('Profile', through='Membership')
    ...

我的会员模式:

class Membership(models.Model):
    ...
    profile = models.ForeignKey('Profile', on_delete=models.CASCADE)
    alliance = models.ForeignKey('Alliance', on_delete=models.CASCADE)
    ...

我认为可行的解决方案(使用信号)看起来像这样:

@receiver(post_save, sender=Alliance)
def create_membership(sender, instance, created, **kwargs):
    if created:
        Membership.objects.create(profile=???, alliance=instance)

'???' 应该是创作者的个人资料。我会很高兴得到任何帮助。

标签: pythondjangosignals

解决方案


信号无法访问触发它的请求,因为它并没有说触发器首先是 HTTP 请求。您可以尝试检查回溯,但这是一个 hacky 解决方案,可能会产生比其价值更多的麻烦。

您需要在创建组的表单视图中执行此操作。例如,在视图中,您可以使用以下命令添加:

from django.views.generic import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
from app.models import Alliance, Membership

class AllianceCreateView(LoginRequiredMixin, CreateView):
    model = Alliance

    def form_valid(self, form):
        self.object = form.save()
        Membership.objects.create(
            profile=self.request.user.profile,
            alliance=self.object
        )
        return HttpResponseRedirect(self.get_success_url())

请注意,建模很奇怪。通常您指定两个ManyToManyFields。Django 会自动添加第二个。因此,您可以在您的Profile:

class Profile(models.Model):
    # ...
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    alliances = models.ManyToManyField(
        'Alliance',
        through='Membership',
        related_name='members'
    )

推荐阅读