python 如何从ForeignKey自动增值到ManyToManyField?

yhived7q  于 2023-06-20  发布在  Python
关注(0)|答案(1)|浏览(87)

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

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

现在我使用序列化器和视图解决方案。有可能用模型吗?

x8diyxa7

x8diyxa71#

有可能用模型吗?
我真的建议将其保留在序列化器中,或者如果不可能,则保留在视图中,因为重写.save()方法通常是有风险的:它最终会让一个对象进入无限递归,或者在**.bulk_create(..)**[Django-doc]的情况下,它会跳过.save()方法,这不能正常工作。
如果你真的想这样做,你可以在 * 之后 * 你在超级级别上执行.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)

但也许根本没有必要把它加到同事身上:您可以添加一个属性来获取所有使用以下方法处理此问题的人员:

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

然后,你可以使用my_board.coworkers(或my_board.coworkers.all())得到author * 和extra_workers的组合。在ManyToManyField中不显式保存作者的好处是,如果您稍后更改了author,而这并不需要担心,那么coworkers将返回“新的”.author.extra_workers

注意:通常使用**settings.AUTH_USER_MODEL[Django-doc]引用用户模型比直接使用User模型[Django-doc]更好。有关详细信息,请参阅文档的 referencing the User model 部分。
注意
related_name=…**参数[Django-doc]是 reverse 中关系的名称,所以本例中从User模型到Board模型。因此,将其命名为前向关系(通常)没有多大意义。因此,您可能需要考虑将author关系重命名为authored_boards

相关问题