문제

나는 다음과 같은 일을하고 싶다 :

Model Limit_Choices_to = { '사용자': 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 SO에 대한 답변에 따라 미들웨어를 사용하여 현재 사용자를 확보하는 데 약간의 성공을 거두었습니다. , 나는 현재 작업을 식별 할 수 있으며, 따라서 운영자로서 사용자의 하위 집합을 이동할 수 있습니다.

다시 말해, 부모 분야의 많은 사람들이 선택한 것을 기반으로, 해당 하위 선택을 어린이 분야에 제공하거나 John, Jim, Jordan 및 Jesse가 작업을 수행 한 경우 해당 이름 만 선택하여 작업을 설명 할 수 있습니다. 그 직무에 대한 내부 및 활동.

BTW, 여기 미들웨어에서의 순진한 시도가 있습니다.

# 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)))

고맙습니다.

도움이 되었습니까?

해결책

좋아, 나는 당신의 작품에 Monkey Wrench를 던지는 것을 싫어하지만 ThreadLocals 해킹을 진지하게 사용할 필요는 없습니다.

사용자는 요청 객체에 있으므로 미들웨어를 사용하여 추출 할 필요가 없습니다. 그것은 모든 관점에 대한 논쟁으로 전달됩니다.

양식 선택을 제한하는 요령은 모델에서 한계 선택을 수행하는 대신 양식에 사용 된 쿼리 세트를 동적으로 변경하는 것입니다.

그래서 당신의 양식은 다음과 같습니다.

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

그리고 당신의 견해는 다음과 같습니다.

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

이것은 단지 빠른 스케치이지만 일반적인 아이디어를 제공해야합니다.

관리자의 ThreadLocals를 피하는 방법이 궁금하다면 읽으십시오. 사용자와 관리자 제임스 베넷.

편집하다: 장고에서 유용한 형태의 트릭 Collin Grady는 또한 __init__ 메소드 양식으로 쿼리 세트를 동적으로 설정하는 예를 보여줍니다.이 예는 위의 예보다 깨끗합니다.

다른 팁

그러나 list_filter로 정의하는 필드는 어떻습니까? 그들은 Limit_choices_to 만 존중합니다. 따라서 django 관리자 필터의 선택을 제한하려면 Limit_choices_to와 일부 미들웨어를 사용하여 현재 사용자를 기반으로 필터링해야합니다. 아니면 더 쉬운 솔루션이 있습니까?

원숭이 렌치를 환영합니다.

나는 또한 다른 방법을 찾았지만 덜 직접적인 것 같습니다.

class ActivityForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ActivityForm, self).__init__(*args, **kwargs)

        if self.initial['job_record']:
            jr = JobRecord.objects.get(pk=self.initial['job_record'])
            self.fields['operators'].queryset = jr.operators

    class Meta:
        model = Activity
        exclude = ('duration',)  

나는 당신의 길이 더 좋다고 생각합니다! 감사합니다 힙!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top