django - 使用中间件限制对外键的选择

标签 django post middleware limit-choices-to

我想做这样的事情:

Model limit_choices_to={'user': user}

有一些差异。

一些模型可能会解释:

class Job(models.Model):
    name = models.CharField(max_length=200)
    operators = models.ManyToManyField(User)

class Activity(models.Model):
    job = models.ForeignKey(Job)
    job_operators = models.ManyToManyField(User, limit_choices_to={user: Job.operators} blank=True, null=True)

注意:语法并不一定正确,而是说明性的。

现在,我使用中间件在获取当前用户方面取得了一些成功,正如 SO 上的一些答案所描述的那样,但是,我希望我可以通过 request.POST 获取当前的作业,这样,如果事件已保存,我将能够识别当前的作业,因此作为运算符(operator)的用户子集将成为事件模型中可供选择的用户集。

换句话说,根据父字段中 ManyToManyField 的选择,向子字段提供子选择,或者,如果 John、Jim、Jordan 和 Jesse 从事某项工作,则仅从这些名称中进行选择描述一项事件的工作,在该工作中并归因于该工作。

顺便说一句,这是我在中间件方面的天真的尝试:

# threadlocals middleware
try:
    from threading import local
except ImportError:
    from django.utils._threading_local import local

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

def get_current_job():
    return getattr(_thread_locals, 'job', None)

class ThreadLocals(object):
    """Middleware that gets various objects from the
    request object and saves them in thread local storage."""
    def process_request(self, request):
        _thread_locals.user = getattr(request, 'user', None)
        _thread_locals.job = getattr(request.POST["job"], 'job', None)

和事件模型:

operators = modes.ManyToManyField(User, limit_choices_to=dict(Q(User.objects.filter(job==threadlocals.get_current_job)))

谢谢。

最佳答案

好吧,我讨厌在你的作品中添加事件 Spanner ,但你真的不需要使用线程本地黑客。

用户位于请求对象中,这意味着不需要使用中间件来提取它。它作为参数传递给每个 View 。

因此,限制表单选择的技巧是动态更改表单中使用的查询集,而不是在模型中进行限制选择。

所以你的表单看起来像这样:

# forms.py
from django import forms
from project.app.models import Activity
class ActivityForm(forms.ModelForm):
    class Meta:
        model Activity

您的 View 将如下所示:

# views.py
...
form = ActivityForm(instance=foo)
form.fields['job_operators'].queryset = \
    User.objects.filter(operators__set=bar)
...

这只是一个快速草图,但应该可以让您了解总体思路。

如果您想知道如何避免管理中的线程本地化,请阅读 Users and the admin作者:詹姆斯·贝内特。

编辑: Useful form tricks in Django Collin Grady 还展示了一个以 __init__ 方法形式动态设置查询集的示例,这比我上面的示例更清晰。

关于django - 使用中间件限制对外键的选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/588240/

相关文章:

python - 获取 django-transmeta 中默认语言的字段值

django - Celery 立即超出了 Heroku 上的内存

c# - WCF Post 请求内容类型 text/xml

php - 通过 AJAX 发送特殊字符( "&lt"、 "&gt"、 "&amp")

php - 拉维尔 5.1 : Unable to get form data in middleware

python - 我做了类似的事情,它抛出 : UnboundLocalError at/local variable 'context' referenced before assignment error

python - 隐藏django表单字段的无值

javascript - 如何从 Facebook 群组获取我所有帖子的列表

python - 如何将具有自定义用户设置的 Django 中间件添加为 Python 包?

c# - Asp.Net Core 2.x 中间件语法