首页 > 解决方案 > 通过 Django Admin 中的多个表查找特定用户的实体

问题描述

我通过stackoverflow搜索了这个特定的场景,但找不到具体的答案,所以我发布了这个。

所以我的问题是我需要在 Django Admin 中向特定用户显示特定记录。我知道我可以通过从对象中get_queryset提取它的方法来获取具体的登录用户。request但问题是我需要查看 6 个表格以获取有关推荐用户的信息,以便我知道要向他显示哪个推荐。

例如,如果我需要显示的记录来自一个Recommendation表,它有一个对 的引用TableA,它有一个对TableB.... 的引用,TableF它有一个对 which 的引用User

我知道我可以通过执行带有多个连接的普通 SQL 查询来做到这一点,但我的猜测是必须有一个 pythonic 或 Django 复杂的解决方案来解决这个问题。但我可能错了。

不幸的是,该模型不在我的控制范围内,我也无法更改它,所以我只能处理现有模型的状态。

提前致谢。

编辑:不幸的是,我不能分享它的细节,但我可以分享它的一般外观。所以我认为这应该足以了解我的问题。

from django.db import models
from django.contrib.auth.models import User


class TableF(models.Model):
    information = models.CharField(max_length=256, null=False)
    user = models.ForeignKey(User, on_delete=models.CASCADE)


class TableE(models.Model):
    information = models.CharField(max_length=256, null=False)
    tableF = models.ForeignKey(TableF, on_delete=models.CASCADE)


class TableC(models.Model):
    information = models.CharField(max_length=256, null=False)
    tableEs = models.ManyToManyField(TableE, through='TableD')


class TableD(models.Model):
    information = models.CharField(max_length=256, null=False)
    tableC = models.ForeignKey(TableC, on_delete=models.CASCADE)
    tableE = models.ForeignKey(TableE, on_delete=models.CASCADE)


class TableA(models.Model):
    information = models.CharField(max_length=256, null=False)
    tableCs = models.ManyToManyField(TableC, through='TableB')


class TableB(models.Model):
    information = models.CharField(max_length=256, null=False)
    tableA = models.ForeignKey(TableA, on_delete=models.CASCADE)
    tableC = models.ForeignKey(TableC, on_delete=models.CASCADE)


class Recommendation(models.Model):
    information = models.CharField(max_length=256, null=False)
    tableA = models.ForeignKey(TableA, on_delete=models.CASCADE)

标签: pythonpython-3.xdjangodjango-modelsdjango-admin

解决方案


you can use a middleware to include de user to the thread locals and catch this user from get_queryset in the model manager.

from threading import local


_thread_locals = local()


def get_current_user():
    return getattr(_thread_locals, 'user', None)


class ThreadLocals(object):
    @staticmethod
    def process_request(request):
        _thread_locals.user = getattr(request, 'user', None)

in the settings


MIDDLEWARE = [
    ...
    'path.to.file.ThreadLocals',
]

from your.path import get_current_user


class TableFManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(creator=get_current_user())


class TableF(models.Model):
    information = models.CharField(max_length=256, null=False)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    objects = TableFManager()


推荐阅读