【问题标题】:How can I implement blocking using Django-relationships?如何使用 Django 关系实现阻塞?
【发布时间】:2023-10-22 05:23:01
【问题描述】:

我一直在使用django-relationships 来允许用户互相关注。如果鲍勃跟随乔。 Bob 将能够看到 Joe 的所有照片。但是,如果 Bob 屏蔽了 John,John 将不是 Bob 的照片。

我的问题是我不知道如何限制来自被阻止用户的内容。我已经看过示例,但似乎仍然找不到解决方案。

假设摄影师是用户的 FK

这是我的 FollowPhoto 资源(此资源返回属于用户关注的人的所有照片):

FollowingPhoto(ModelResource):
     photographer = fields.ForeignKey(PhotographerResource, 'photographer', full=True)
     class Meta:
          queryset = Photo.objects.all().order_by('-postTime')
          resource_name = 'following'
          fields = ['id', 'title', 'url', 'likes','postTime','photographer', 'location_id', 'location_name']
          authentication = BasicAuthentication()
          authorization = DjangoAuthorization()
          serializer = Serializer(formats=['json'])
          include_resource_uri = False
          filtering = {
                 'postTime': ALL,
                 'photographer' : ALL_WITH_RELATIONS,


         }

     def get_object_list(self, request):
             return super(FollowingPhoto, self).get_object_list(request).filter(photographer__user__in = request.user.relationships.following())

现在您可能已经注意到,我的 get_object_list 会返回我关注的用户的所有内容。如何防止被屏蔽的用户出现在此列表中?

Django-relationships 应用在 postgresql 中生成两个表,下表是关系表:

    id       from_user    to_user_id   status_id            created
[PK] serial   integer      integer                         timestamp
    6            1            5           1         2012-10-05 20:10:29.848667+00"
    7            1            3           1         2012-10-05 20:11:23.319961+00"

另一个表是relationships_relationshipstatus表:

    id          name          verb         from_slug        login_required   private
[PK] serial   character     character   character varying      boolean       boolean
    1         Following      follow         friends             FALSE         FALSE
    2         Blocking        block         !                   TRUE          TRUE

下面我添加了一个指向 Django-relationships models.py 的链接,以便您进一步澄清:

models.py

【问题讨论】:

  • 您可以将您的模型发布到粘贴箱或其他东西中,以便我进行快速测试吗?
  • @FracisYaconiello 我已经在底部添加了 models.py 的链接!:)

标签: python django tastypie blocking relationships


【解决方案1】:

在我看来,您只需要一个 .exclude 子句 - 类似于:

def get_object_list(self, request):
     return super(FollowingPhoto, self).get_object_list(request).filter(photographer__user__in = request.user.relationships.following()).exclude(photographer__user__in=request.user.relationships.blocking())

如果 Bob 屏蔽了 John,这将阻止 Bob 看到 John 的照片。鉴于 Bob 只在 Bob 关注 John 时才能看到 John 的照片,除非 Bob 同时关注并阻止 John,否则它不会做任何事情,这对我来说似乎很奇怪 - 如果 John 阻止 Bob,您是否希望 Bob 看不到 John 的照片?如果是这样:

def get_object_list(self, request):
    return super(FollowingPhoto, self).get_object_list(request).filter(photographer__user__in = request.user.relationships.following()).exclude(photographer__user__in=request.user.relationships.blockers())

【讨论】:

  • !抱歉造成混淆,我只是编辑了问题以使其更清晰,是的,您绝对正确,如果约翰阻止鲍勃,我不希望鲍勃看到约翰的照片。我会试一试,让你知道它是否有效!
  • idk 如果这对 OP 有帮助,但它在完全不同的情况下帮助了我,最终我学习了数据库规范化:P 谢谢
【解决方案2】:

创建自定义管理器。取决于您是选择用户可以看到的所有照片,还是选择允许您看到照片的所有用户,这对您是否需要RelationshipManager 或 照片管理器。我假设您想要照片提要 - 您可以调整它以使用一些 sql 轻松限制用户。

PhotosManager(models.Manager):
    def get_unblocked(self, user):
        sql = """SELECT myapp_photo.* 
            FROM myapp_photo
            INNER JOIN auth_user
                ON myapp_photo.user_id = auth_user.id
            WHERE auth_user.id != %d /*DO NOT SHOW YOUR OWN PHOTOS*/
            AND myapp_photo.user_id NOT IN(
                SELECT myapp_blocked.blocked_user_id
                FROM myapp_blocked
                WHERE myapp_blocked.user_id = %d
            )""" % (user.pk, user.pk)

        return self.model.objects.raw(sql)

对不起,糟糕的sql,我不知道你的表结构我只是想说明一点

然后在你的照片模型中添加objects = PhotosManager()

您现在可以获得未在您的视图中被阻止的照片列表:

Photos.objects.get_unblocked(request.user)

编辑:

我刚刚意识到我的代码只考虑了被屏蔽的用户而不是关注者。再次不知道你的表结构我只是在猜测。您可以添加另一个 AND myapp_photo.user_id IN( 子句以仅允许来自关注用户的照片。此外,您肯定可以编写更好的 sql,这是一个快速而肮脏的示例。我的解决办法:写一个管理器,实际提供的sql只是为了说明。

【讨论】:

  • 嘿@FrancisYaconello,我已经为这个问题添加了更多信息,希望这能更清楚地说明问题!如果我需要提供更多信息,请告诉我,感谢您的帮助!