在 Django 中向多对多关系添加记录的正确方法

发布于 2024-10-10 01:57:16 字数 723 浏览 4 评论 0原文

首先,我计划在 Google App Engine 上运行我的项目,因此我使用 djangoappengine据我所知,它不支持 django 的 ManyToManyField 类型。因此,我像这样设置了我的模型:

from django.db import models
from django.contrib.auth.models import User

class Group(models.Model):
    name = models.CharField(max_length=200)

class UserGroup(models.Model):
    user = models.ForeignKey(User)
    group = models.ForeignKey(Group)

在页面上,我有一个表单字段,人们可以在其中输入组名称。我希望此表单字段的结果为用户-组组合创建一个 UserGroup 对象,如果该组尚不存在,则创建一个新的 Group 对象。起初,我开始使用 add_group 方法将此逻辑放入 UserGroup 类中,但很快意识到将其放入 UserGroup 类中并没有真正意义。这样做的正确方法是什么?我看到了一些关于模型经理的东西。这是这些的用途吗?

First off, I'm planning on running my project on google app engine so I'm using djangoappengine which as far as I know doesn't support django's ManyToManyField type. Because of this I've setup my models like this:

from django.db import models
from django.contrib.auth.models import User

class Group(models.Model):
    name = models.CharField(max_length=200)

class UserGroup(models.Model):
    user = models.ForeignKey(User)
    group = models.ForeignKey(Group)

On a page I have a form field where people can enter a group name. I want the results from this form field to create a UserGroup object for the user - group combination and if the group doesn't yet exist create a new Group object. At first I started putting this logic in the UserGroup class with a add_group method but quickly realized that it doesn't really make sense to put this in the UserGroup class. What would the proper way of doing this be? I saw some stuff about model managers. Is this what those are for?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吃素的狼 2024-10-17 01:57:16

来自 Django 文档

管理器是向 Django 模型提供数据库查询操作的接口

因此管理器不是创建模型新实例的方法。

我只会有一个 Group 模型的构造函数,它从关键字参数中提取 User (如果给定的话)并创建一个新的 UserGroup

因此,如果您将新的 Group 实例化为 Group(name='group name', user=some_user) 构造函数可能会删除 user 关键字参数并使用该用户创建适当的UserGroup

class Group(models.Model):
    name = models.CharField(max_length=200)

    def __init__(self, *args, **kwargs):
        # Remove user from the kwargs.
        # It is important that user is removed from the kwargs before calling
        # the super.__init__(). This is because the `user` kwarg is not expected.
        user = kwargs.pop('user', None)

        # call the normal init method
        super(Group, self).__init__(*args, **kwargs)

        # Create the UserGroup instance for the specified user
        if user is not None:
            # Maybe some other logic here ...
            UserGroup(user=user, group=self).save()

这样,如果您在实例化Group时提供用户,则它将创建一个UserGroup并且不会执行其他任何操作。

当然,您同样可以在 UserGroup 模型的构造函数中执行类似的操作,这并不是那么重要,它只是取决于哪个隐喻对您的代码有意义。

编辑:

修复评论中指出的问题:

...
def __init__(self, *args, **kwargs):
    ...
    self._user_group = UserGroup(user=user, group=self)

def save(self, *args, **kwargs):
    super(Group, self).save(*args, **kwargs)
    self._user_group.save()

From the Django docs:

A Manager is the interface through which database query operations are provided to Django models

So a manager is not the way to create new instances of a model.

I would just have a constructor for the Group model which pulls the User (if it is given) from the keyword arguments and creates a new UserGroup.

So if you instantiated a new Group as Group(name='group name', user=some_user) the constructor could strip the user keyword argument away and create the appropriate UserGroup with that user:

class Group(models.Model):
    name = models.CharField(max_length=200)

    def __init__(self, *args, **kwargs):
        # Remove user from the kwargs.
        # It is important that user is removed from the kwargs before calling
        # the super.__init__(). This is because the `user` kwarg is not expected.
        user = kwargs.pop('user', None)

        # call the normal init method
        super(Group, self).__init__(*args, **kwargs)

        # Create the UserGroup instance for the specified user
        if user is not None:
            # Maybe some other logic here ...
            UserGroup(user=user, group=self).save()

This way if you provide a user when instantiating your Group it will create a UserGroup and will do nothing otherwise.

Of course you could equally do a similar thing in the constructor of the UserGroup model, it is not really that important, it just depends which metaphorically makes sense to your code.

EDIT:

A fix to the problems pointed out in the comments:

...
def __init__(self, *args, **kwargs):
    ...
    self._user_group = UserGroup(user=user, group=self)

def save(self, *args, **kwargs):
    super(Group, self).save(*args, **kwargs)
    self._user_group.save()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文