Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

查询我关注的及屏蔽的用户 #12

Open
codetalks-new opened this issue Feb 27, 2019 · 0 comments
Open

查询我关注的及屏蔽的用户 #12

codetalks-new opened this issue Feb 27, 2019 · 0 comments

Comments

@codetalks-new
Copy link
Owner

开发及测试数据准备

  1. 通过迁移脚本创建一些互相关注或屏蔽的开发用户
    ./manage_dev.py makemigrations wepost_sns --empty --name dev_user_follow_some_user

迁移脚本如下:

from django.db import migrations

from wepost.apps.auth.models import WepostUser
from wepost.apps.sns.services import UserRelationService


def dev_user_follow_block_some_users(apps,se):
    import random
    dev_users = list(WepostUser.objects.filter(username__istartswith="dev"))
    user_set = set(dev_users)
    for user in user_set:
        service = UserRelationService(user)
        other_users = set(user_set)
        other_users.remove(user)
        k = int(len(other_users) * 0.1)
        blocked_users = set(random.choices(list(other_users), k=k))
        for to in other_users:
            if to not in blocked_users:
              service.follow(to)
            else:
              service.block(to)





class Migration(migrations.Migration):

    dependencies = [
        ('wepost_sns', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(dev_user_follow_block_some_users)
    ]

创建多对多关联

class WepostUser(AbstractUser):
  followed_or_blocked = models.ManyToManyField('self',
                                               symmetrical=False,
                                               through='wepost_sns.UserRelation',
                                               through_fields=('from_user', 'to_user'))

注意

  1. 这里的多对多关联是关联的自身上。所以引用时使用特殊的 self 标识。
  2. 同时在我们这里采用了中间表,并且表示的也并非对称性的关系,所以 symmetrical=False
  3. through 字段中由于 UserRelation 数据模型声明在 wepost_sns app中。所以在 wepost_auth app 中引用需要加全限定。
  4. through_fields 中两个字段的逻辑是 field1from_user 相当于 source, field2to_user 相当于 target.

原来 from_userto_user 的 related_name 的设置的名称的语义不正确。更新后如下:

class UserRelation(BaseModel):
  from_user = models.ForeignKey(WepostUser, on_delete=models.CASCADE, verbose_name="用户",
                                related_name="userrelation_from", )
  to_user = models.ForeignKey(WepostUser, on_delete=models.CASCADE, verbose_name="目标用户", related_name="userrelation_to")

然后实现的查询接口代码如下:

  def _query_related(self, state: UserRelationState, keyword: str = None):
    user_set = self.user.followed_or_blocked.filter(userrelation_to__state=state).order_by(
      "-userrelation_to__created")
    if keyword:
      user_set = user_set.filter(username__icontains=keyword)

    return user_set

  def query_followed_users(self, keyword: str = None):
    return self._query_related(state=UserRelationState.FOLLOWING, keyword=keyword)

  def query_blocked_users(self, keyword: str = None):
    return self._query_related(state=UserRelationState.BLOCKING, keyword=keyword)

测试相关代码,跟我的节点中测试代码逻辑类同,因此在此不再赘述。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant