简体   繁体   English

Django:在序列化程序中查询关系模型

[英]Django: Query relational models in serializer

I have a Project and Memberships model where each project has a list of members.我有一个项目和成员资格 model,其中每个项目都有一个成员列表。 I need to find out if the current logged in user is listed as a member on the project from the project serializer, but I can't seem to get the request correct in my get_i_am_member method.我需要从项目序列化程序中查明当前登录的用户是否被列为项目的成员,但我似乎无法在我的get_i_am_member方法中获得正确的请求。 I need to pass the project id from the Project model to the Membership model to filter the data, then check if the user in the filtered memberships model matches the user making the request.我需要将 Project model 中的项目 ID 传递给 Membership model 以过滤数据,然后检查过滤后的成员资格 model 中的用户是否与发出请求的用户匹配。 Can someone please assist?有人可以帮忙吗? Here is my code:这是我的代码:

######################################################
# Serializer
######################################################

class ProjectSerializer(LightWeightSerializer):
    id = Field()
    name = Field()
    slug = Field()
    description = Field()
    created_date = Field()
    modified_date = Field()
    owner = MethodField()
    members = MethodField()
    is_private = Field()
    anon_permissions = Field()
    public_permissions = Field()
    is_looking_for_people = Field()
    looking_for_people_note = Field()
    i_am_member = MethodField()
    i_am_admin = MethodField()
    my_permissions = MethodField()

    def get_members(self, project):
        members = Membership.objects.filter(project_id=project.id).select_related()
        return MembershipSerializer(members, many=True, context=self.context).data

    def get_i_am_member(self, request):
        members_list = Membership.objects.filter(project_id=request.project.id).select_related('user')
        for member in members_list:
            if member.user == request.username:
                print(member.user)
                print("True")
                return True
            else:
                print(member.user)
                print("False")
            return False
######################################################
# Models
######################################################
class Project(models.Model):
    name = models.CharField(max_length=250, null=False, blank=False,
                            verbose_name=_("name"))
    slug = models.SlugField(max_length=250, unique=True, null=False, blank=True,
                            verbose_name=_("slug"))
    description = models.TextField(null=False, blank=False,
                                   verbose_name=_("description"))

    logo = models.FileField(upload_to=get_project_logo_file_path,
                            max_length=500, null=True, blank=True,
                            verbose_name=_("logo"))

    created_date = models.DateTimeField(null=False, blank=False,
                                        verbose_name=_("created date"),
                                        default=timezone.now)
    modified_date = models.DateTimeField(null=False, blank=False,
                                         verbose_name=_("modified date"))
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
                              related_name="owned_projects", verbose_name=_("owner"), on_delete=models.CASCADE)

    members = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="projects",
                                     through="Membership", verbose_name=_("members"),
                                     through_fields=("project", "user"))

    is_private = models.BooleanField(default=True, null=False, blank=True,
                                     verbose_name=_("is private"))
    anon_permissions = ChoiceArrayField(
        models.TextField(null=False, blank=False, choices=ANON_PERMISSIONS),
        null=True,
        blank=True,
        default=list,
        verbose_name=_("anonymous permissions")
    )
    public_permissions = ChoiceArrayField(models.TextField(null=False, blank=False, choices=MEMBERS_PERMISSIONS),
                                    null=True, blank=True, default=list, verbose_name=_("user permissions"))

    is_featured = models.BooleanField(default=False, null=False, blank=True,
                                      verbose_name=_("is featured"))

    class Meta:
        db_table = "projects"
        verbose_name = "project"
        verbose_name_plural = "projects"
        ordering = ["name", "id"]
        index_together = [
            ["name", "id"],
        ]


class Membership(models.Model):
    # This model stores all project memberships. Also
    # stores invitations to memberships that do not have
    # assigned user.

    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, default=None,
                             related_name="memberships", on_delete=models.CASCADE)
    project = models.ForeignKey(Project, null=False, blank=False,
                                related_name="memberships", on_delete=models.CASCADE)
    role = models.ForeignKey('core.Role', null=False, blank=False,
                             related_name="memberships", on_delete=models.CASCADE)
    is_admin = models.BooleanField(default=False, null=False, blank=False)

    user_order = models.BigIntegerField(default=timestamp_ms, null=False, blank=False,
                                        verbose_name=_("user order"))

    class Meta:
        db_table = "memberships"
        verbose_name = "membership"
        verbose_name_plural = "memberships"
        unique_together = ("user", "project",)
        ordering = ["project", "user__full_name", "user__username", "user__email"]

    def get_related_people(self):
        related_people = get_user_model().objects.filter(id=self.user.id)
        return related_people

    def clean(self):
        # TODO: Review and do it more robust
        memberships = Membership.objects.filter(user=self.user, project=self.project)
        if self.user and memberships.count() > 0 and memberships[0].id != self.id:
            raise ValidationError(_('The user is already member of the project'))

By default drf passes request object using context, so modification should be:默认情况下,drf 使用上下文传递请求 object,因此修改应为:

def get_i_am_member(self, project):
    members_list = Membership.objects.filter(project_id=project.id).select_related('user')
    for member in members_list:
        if member.user == self.context['request'].user:
            print(member.user)
            print("True")
            return True
        else:
            print(member.user)
            print("False")
        return False

But in case you manually call serializer, you need to pass it:但是如果您手动调用序列化程序,则需要传递它:

ProjectSerializer(instance=project, context={'request': request})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM