使用来自中间 table 的信息从 manydomanyfield 检索用户列表

Retrieve a user list from a manydomanyfield with information from an intermediate table

自从我试图用中间人的信息检索用户列表以来已经有几个小时了table。

所以我有一个工作区模型,它是一个包含用户的多对多字段

还有一个中介table来区分经典用户和工作区管理员

我想显示用户列表,并在列表中添加一个代表管理员的小图标。

但不幸的是,Django 似乎很难同时显示工作区的用户列表和中间信息 table。

无论如何,我查看了 Django 的文档我都没有设法找到如何做。

models.py

class Workspace(models.Model):
    name = models.CharField(max_length=250, verbose_name="Nom du workspace")
    members = models.ManyToManyField(User, through='Membership', verbose_name="Membres du workspace")
    token = models.CharField(max_length=500)    # token statique
    join_token = models.CharField(max_length=500)   # token dynamique
    join_token_date = models.DateTimeField(auto_now_add=False, null=True, blank=True)
    payday = models.DateField(max_length=10, verbose_name="Jour de paye", null=True, blank=True)
    planning_image = ProcessedImageField(upload_to='planning',
                                                null=True, 
                                                blank=True,
                                                processors=[ResizeToFill(1299, 937)],
                                                format='JPEG',
                                                options={'quality': 100})
    planning_thumbnail = ImageSpecField(source='planning_image',
                                        processors=[ResizeToFill(280, 202)],
                                        format='JPEG',
                                        options={'quality': 100})

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('create-workspace')


class Membership(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    workspace = models.ForeignKey(Workspace, on_delete=models.CASCADE)
    is_manager = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True)

views.py

@login_required
def workspace_detail(request, token):

    ins_workspace = get_object_or_404(Workspace, token=token)
    list_members = ins_workspace.members.all()

    for member in list_members:
        if member == request.user:
            current_user = Membership.objects.get(workspace=ins_workspace, user=request.user)
            context = {
                        'name': ins_workspace.name,
                        'token': ins_workspace.token,
                        'list_members': list_members,
                        'payday': ins_workspace.payday,
                        'is_manager': current_user.is_manager,
                        }
            return render(request, 'workspace/workspace_detail.html', context)
        else:
            return HttpResponseForbidden()

template.html

{% for item in list_members %}
   {{ item.username }}
{% endfor %}

这就是我想要的:

template.html

{% for item in list_members %}
   {% item.is_manager %}
      {{ item.username }} (♔)
   {% else %}
      {{ item.username }}
{% endfor %}

你可以这样做:

使用相关名称更新会员模型:

class Membership(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="membership")
    workspace = models.ForeignKey(Workspace, on_delete=models.CASCADE)
    is_manager = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True)

然后您可以像下面这样更新您的视图:

from django.db.models import F

@login_required
def workspace_detail(request, token):

    ins_workspace = get_object_or_404(Workspace, token=token)
    list_members = ins_workspace.members.all().annotate(is_manager=F('membership__is_manager'))

    context = {
            'name': ins_workspace.name,
            'token': ins_workspace.token,
            'list_members': list_members,
            'payday': ins_workspace.payday,
            'is_manager': request.user.membership.get(workspace=ins_workspace).is_manager,
     }
     return render(request, 'workspace/workspace_detail.html', context)

这应该可以解决问题。

这里我所做的是,我正在使用a reverse relation to get is_manager value from membership model. I am annotating that value in the queryset using F