我正在处理涉及通道/帖子机制的项目。我目前正在通过将名为“已删除”的字段设置为删除时间戳来实现“删除”帖子的功能。它需要保持历史意义(最后的活动),并追踪那些煽动性的人(该服务是整个项目的基于特权的部分)。Django ORM根据字段值过滤相关对象?
models.py
class Post(models.Model):
deleted = models.DateTimeField(null=True, blank=True)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now_add=True)
post_text = models.CharField(max_length=1000)
post_to = models.ForeignKey('Channel', related_name='post_to_channel')
post_from = models.ForeignKey(User, related_name='user_from_post')
class Channel(models.Model):
created_date = models.DateTimeField(auto_now_add=True)
channel_title = models.CharField(max_length=50, unique=True)
channel_description = models.CharField(max_length=100)
channel_creator = models.ForeignKey(User)
channel_private = models.BooleanField(default=False)
channel_users = models.ManyToManyField(User, through='Membership', related_name='channels', blank=True)
channel_posts = models.ManyToManyField(Post, related_name='channel_post', blank=True)
initial_invites = models.ForeignKey(User, null=True, blank=True, related_name='initial_invites')
objects = models.Manager()
class Membership(models.Model):
channel = models.ForeignKey(Channel)
channel_user = models.ForeignKey(User, related_name='channel_membership')
join_date = models.DateTimeField(auto_now_add=True)
我有一个更新的“删除”端点“后”对象的领域是从零时间戳。那么我该如何避免在“频道”级别查询时返回所有包含时间戳的帖子,通过他们的关系和单独的序列化程序加载帖子?基本上,我需要能够查询“频道”,并获得我参与的频道列表,然后通过他们与ManyToMany的关系,使用“发布”加载所有相关帖子,排除那些在“已删除”字段中具有值的用户。这可能不需要为每个通道调用ORM,然后过滤掉已删除的帖子?要清楚的是,如果存在已删除的帖子,则“频道”仍然应该通过,只有“帖子”本身应该被隐藏。
如果我没有提供足够的信息,请让我知道你需要看什么。
如果答案是没有重复的ORM调用,这是不可能的,建议其他选项将被赞赏,其中包括权衡将这些帖子归档到重复模型的选项,而不会在这些情况下调用钩子并删除原件。
编辑1: 添加的属性在所选择的答案指出,然而它不能看到self.channel_posts
。 models.py
class Channel(models.Model):
created_date = models.DateTimeField(auto_now_add=True)
channel_title = models.CharField(max_length=50, unique=True)
channel_description = models.CharField(max_length=100)
channel_creator = models.ForeignKey(User)
channel_private = models.BooleanField(default=False)
channel_users = models.ManyToManyField(User, through='Membership', related_name='channels', blank=True)
channel_posts = models.ManyToManyField(Post, related_name='channel_post', blank=True)
initial_invites = models.ForeignKey(User, null=True, blank=True, related_name='initial_invites')
objects = models.Manager()
@property
def get_viewable_posts(self):
print (self.channel_users) # prints []
print (self.channel_posts) # prints []
return CourtyardPost.objects.filter(deleted__isnull=True, courtyard_post_to=self.pk) #works, but adds IO strain
目前,如上所示它是每个通道的ORM呼叫,但打印self.channel_posts
或self.channel_users
返回一个空列表,在所有方案。该物业被称为Django的REST框架的串行器的一部分如下面执行:
class CourtyardChannelSerializer(serializers.ModelSerializer):
current_user = serializers.SerializerMethodField('_user')
post_to_channel = CourtyardPostSerializer(many=True, source='get_viewable_posts', read_only=True)
most_recent = CourtyardPostSerializer(many=True, source='latest_post', read_only=True)
channel_users = CourtyardUserSerializer(many=True, read_only=True)
)
invite_list = serializers.ReadOnlyField(source='get_invitation_set', required=False)
def _user(self, obj):
user = self.context['request'].user.username
return user
我居然遇到了一个问题,试图以此为-是,由于某种原因,自' .channel_posts'是一个空数组,无论是否在属性点(通过打印)过滤。我最终需要将其重新过滤为所有帖子的过滤查询集,但是这种方式在大规模(由于有太多数据库调用)的情况下效果不佳,为什么它会显示为空?你的答案仍然是最干净的,只是希望它可以像你写的那样工作,而不是我的临时版本。无论哪种方式,感谢您的帮助和时间! – AntonMiles
如果您完全按照原样运行代码,那么显然您会在数据库中为“第一个”通道获取active_posts。由于Channel.objects.first()返回数据库中的第一个通道,因此可以使用 。 难道第一个频道没有帖子吗? – Ramast
我调整了它,允许它使用'active_posts'作为序列化程序ManyToMany关系表示形式的源代码,我将编辑问题来说明这一点,但它从不会在我的默认用户的任何通道中看到任何内容,谁在开始删除功能之前拥有可用的帖子,以及之后发布的人员(可以工作,并且可以通过不同的端点查看)。它仍然是最好的答案,并且将它交换为查询集合,只是希望减少数据库IO应变。 *编辑清晰。 – AntonMiles