如何将外键的值自动添加到多对多字段?

huangapple go评论63阅读模式
英文:

How to auto add value from ForeignKey to ManyToManyField?

问题

所以我需要自动将作者添加到同事中。

    """Board 的模型定义。"""

    作者 = models.ForeignKey(
        to=User,
        on_delete=models.CASCADE,
        related_name="作者",
    )
    名称 = models.CharField(max_length=24, blank=False)
    同事 = models.ManyToManyField(
        to=User,
        blank=True,
    )

目前我使用序列化器和视图解决方案。
是否可能通过模型实现?

英文:

So I need auto add author to coworkers.

class Board(models.Model):
    """Model definition for Board."""

    author = models.ForeignKey(
        to=User,
        on_delete=models.CASCADE,
        related_name="author",
    )
    name = models.CharField(max_length=24, blank=False)
    coworkers = models.ManyToManyField(
        to=User,
        blank=True,
    )

For now I use serializer and view solution.
Is it possible do with model?

答案1

得分: 0

Is it possible do with model?
这是否可以使用模型来实现?

I would really advise to keep this in the serializer, or if that is not possible, the view, since overriding the .save() method often is risky: it can eventually get one into infinite recursion, or in case of a .bulk_create(..) [Django-doc], it will skip the .save() method, and this not work properly.
我建议将这部分代码放在序列化器中,如果不可能的话,放在视图中,因为经常覆盖 .save() 方法是有风险的:它最终可能会导致无限递归,或者在使用 .bulk_create(..) [Django-doc] 时会跳过 .save() 方法,导致功能不正常。

If you really want to do this, you can add this after you perform the .save() on the super level, so:
如果你确实想这样做,可以在执行父级的 .save() 后添加以下代码,如下:

from django.conf import settings

class Board(models.Model):
    """Model definition for Board."""

    author = models.ForeignKey(
        to=settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='author',
    )
    name = models.CharField(max_length=24, blank=False)
    coworkers = models.ManyToManyField(
        to=settings.AUTH_USER_MODEL,
        blank=True,
    )

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        self.coworkers.add(self.author)

but perhaps it is simply not necessary to add it to the co-workers: you can add a property to obtain all people that work on this with:
但也许将它添加到协作人中并不是必要的:你可以添加一个属性来获取所有与之合作的人:

from django.conf import settings
from django.contrib.auth import get_user_model

class Board(models.Model):
    """Model definition for Board."""

    author = models.ForeignKey(
        to=settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='author',
    )
    name = models.CharField(max_length=24, blank=False)
    extra_workers = models.ManyToManyField(
        to=settings.AUTH_USER_MODEL,
        blank=True,
    )

    @property
    def coworkers(self):
        return get_user_model().objects.filter(
            Q(pk=self.author_id) | Q(board_set=self)
        )

Then you can use my_board.coworkers (or my_board.coworkers.all()) to get the author and the extra_workers combined. The advantage of not saving the author explicitly in the ManyToManyField, is that if you later change the author that is not something to worry about, the coworkers will then return the "new" .author as well as the .extra_workers.
然后你可以使用 my_board.coworkers(或 my_board.coworkers.all())来获取 author extra_workers 的组合。不在 ManyToManyField 中明确保存作者的优点是,如果以后更改作者,不需要担心,coworkers 将返回 "新" 的 .author 以及 .extra_workers

Note: It is normally better to make use of the settings.AUTH_USER_MODEL&nbsp;<sup>[Django-doc]</sup> to refer to the user model, than to use the User model&nbsp;<sup>[Django-doc]</sup> directly. For more information you can see the referencing the User model section of the documentation.
注意:通常最好使用 settings.AUTH_USER_MODEL&nbsp;<sup>[Django-doc]</sup> 来引用用户模型,而不是直接使用 User 模型&nbsp;<sup>[Django-doc]</sup>。有关更多信息,请参阅文档中的 引用 User 模型 部分

Note: The <code>related_name=&hellip;</code> parameter&nbsp;<sup>[Django-doc]</sup>
is the name of the relation in reverse, so from the User model to the Board
model in this case. Therefore it (often) makes not much sense to name it the
same as the forward relation. You thus might want to consider renaming the <s>author</s> relation to authored_boards.
注意<code>related_name=&hellip;</code> 参数&nbsp;<sup>[Django-doc]</sup>
是反向关系的名称,所以在这种情况下是从 User 模型到 Board 模型。因此,将其命名为与正向关系相同通常没有太多意义。因此,你可能要考虑将 <s>author</s> 关系重命名为 authored_boards

英文:

> Is it possible do with model?

I would really advise to keep this in the serializer, or if that is not possible, the view, since overriding the .save() method often is risky: it can eventually get one into infinite recursion, or in case of a .bulk_create(..) [Django-doc], it will skip the .save() method, and this not work properly.

If you really want to do this, you can add this after you perform the .save() on the super level, so:

<pre><code>from django.conf import settings

class Board(models.Model):
&quot;&quot;&quot;Model definition for Board.&quot;&quot;&quot;

author = models.ForeignKey(
    to=settings.AUTH_USER_MODEL,
    on_delete=models.CASCADE,
    related_name=&#39;author&#39;,
)
name = models.CharField(max_length=24, blank=False)
coworkers = models.ManyToManyField(
    to=settings.AUTH_USER_MODEL,
    blank=True,
)

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)
    self&lt;b&gt;.coworkers.add(self.author)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

but perhaps it is simply not necessary to add it to the co-workers: you can add a property to obtain all people that work on this with:

<pre><code>from django.conf import settings
from django.contrib.auth import get_user_model

class Board(models.Model):
&quot;&quot;&quot;Model definition for Board.&quot;&quot;&quot;

author = models.ForeignKey(
    to=settings.AUTH_USER_MODEL,
    on_delete=models.CASCADE,
    related_name=&#39;author&#39;,
)
name = models.CharField(max_length=24, blank=False)
extra_workers = models.ManyToManyField(
    to=settings.AUTH_USER_MODEL,
    blank=True,
)

@property
def coworkers(self):
    return get_user_model().objects.filter(
        Q(pk=self.author_id) | Q(board_set=self)
    )&lt;/code&gt;&lt;/pre&gt;

Then you can use my_board.coworkers (or my_board.coworkers.all()) to get the author and the extra_workers combined. The advantage of not saving the author explicitly in the ManyToManyField, is that if you later change the author that is not something to worry about, the coworkers will then return the "new" .author as well as the .extra_workers.


> Note: It is normally better to make use of the settings.AUTH_USER_MODEL&nbsp;<sup>[Django-doc]</sup> to refer to the user model, than to use the User model&nbsp;<sup>[Django-doc]</sup> directly. For more information you can see the referencing the User model section of the documentation.


> Note: The <code>related_name=&hellip;</code> parameter&nbsp;<sup>[Django-doc]</sup>
> is the name of the relation in reverse, so from the User model to the Board
> model in this case. Therefore it (often) makes not much sense to name it the
> same as the forward relation. You thus might want to consider renaming the <s>author</s> relation to authored_boards.

huangapple
  • 本文由 发表于 2023年6月19日 04:50:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76502484.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定