Model Limit_Choices_to = { '사용자': user}
문제
나는 모든 문서로 갔다. 또한 IRC 채널 (BTW A Great Community)에 갔다. 그들은 '현재 사용자'가 외국인에있는 필드에서 모델과 제한 선택을 할 수 없다고 나에게 말했다. 나는 이것을 예를 들어 설명하려고 노력할 것이다 :
class Project(models.Model):
name = models.CharField(max_length=100)
employees = models.ManyToManyField(Profile, limit_choices_to={'active': '1'})
class TimeWorked(models.Model):
project = models.ForeignKey(Project, limit_choices_to={'user': user})
hours = models.PositiveIntegerField()
물론 그 코드는 '사용자'객체가 없기 때문에 작동하지 않지만 그것은 내 아이디어였으며 현재 사용자가 프로젝트를 가지고있는 선택을 제한하기 위해 '사용자'를 모델로 보내려고했습니다. '내가없는 곳에 프로젝트를보고 싶다.
당신이 저를 도울 수 있거나 조언을 드릴 수 있다면 대단히 감사합니다. 모든 앱을 쓰고 싶지는 않습니다. 나는 내 머리 속에 이것으로 2 일이 있고 그것을 알아낼 수 없다 :(
업데이트: 솔루션은 여기에 있습니다. http://collingrady.wordpress.com/2008/07/24/useful-form-tricks-in-django/ 배상 request.user
모델에.
해결책
원하는 경우 ThreadLocals를 사용하십시오 현재의 이 모델을 편집하는 사용자. ThreadLocals Middleware는 현재 사용자를 프로세스 전체 변수로 만듭니다. 이 미들웨어를 가져 가십시오
from threading import local
_thread_locals = local()
def get_current_user():
return getattr(getattr(_thread_locals, 'user', None),'id',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)
미들웨어 클래스 사용 방법에 대한 설명서를 확인하십시오. 그런 다음 코드의 어느 곳에서나 호출 할 수 있습니다
user = threadlocals.get_current_user
다른 팁
모델 자체는 현재 사용자에 대해 아무것도 모르지만 모델 객체를 작동하는 양식 (및 양식 재설정 에서이 사용자에게 제공 할 수 있습니다. choices
필요한 필드를 위해).
관리자 사이트 에서이 문제가 필요한 경우 시도해 볼 수 있습니다. raw_id_admin
와 함께 django-granular-permissions
(http://code.google.com/p/django-granular-permissions/ 그러나 나는 내 장고에서 빠르게 일할 수 없었지만 1.0을 위해 충분히 신선한 것 같습니다 ...).
마침내 관리자에 SelectBox가 크게 필요하면 해킹해야합니다. django.contrib.admin
그 자체.
현재 사용자에게 선택을 제한하는 것은 정적 모델 정의가 아니라 요청 사이클에서 동적으로 발생 해야하는 일종의 검증입니다.
다시 말해 : 당신이 창조하는 시점에서 사례 이 모델에서 당신은보기에있을 것이며 그 시점에서 현재 사용자에게 액세스 할 수 있으며 선택을 제한 할 수 있습니다.
그런 다음 request.user에 전달하려면 사용자 정의 modelform이 필요합니다. 여기에서 예제를 참조하십시오.http://collingrady.wordpress.com/2008/07/24/useful-form-tricks-in-django/
from datetime import datetime, timedelta
from django import forms
from mysite.models import Project, TimeWorked
class TimeWorkedForm(forms.ModelForm):
def __init__(self, user, *args, **kwargs):
super(ProjectForm, self).__init__(*args, **kwargs)
self.fields['project'].queryset = Project.objects.filter(user=user)
class Meta:
model = TimeWorked
그런 다음 당신의 견해로 :
def time_worked(request):
form = TimeWorkedForm(request.user, request.POST or None)
if form.is_valid():
obj = form.save()
# redirect somewhere
return render_to_response('time_worked.html', {'form': form})
여기에 있습니다 요리 책 ThreadLocals 및 사용자
Django 1.8.x / Python 2.7.x의 클래스 기반 일반보기를 사용하여 동료와 제가 생각해 냈습니다.
models.py :
# ...
class Proposal(models.Model):
# ...
# Soft foreign key reference to customer
customer_id = models.PositiveIntegerField()
# ...
in forms.py :
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.forms import ModelForm, ChoiceField, Select
from django import forms
from django.forms.utils import ErrorList
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from .models import Proposal
from account.models import User
from customers.models import customer
def get_customers_by_user(curUser=None):
customerSet = None
# Users with userType '1' or '2' are superusers; they should be able to see
# all the customers regardless. Users with userType '3' or '4' are limited
# users; they should only be able to see the customers associated with them
# in the customized user admin.
#
# (I know, that's probably a terrible system, but it's one that I
# inherited, and am keeping for now.)
if curUser and (curUser.userType in ['1', '2']):
customerSet = customer.objects.all().order_by('company_name')
elif curUser:
customerSet = curUser.customers.all().order_by('company_name')
else:
customerSet = customer.objects.all().order_by('company_name')
return customerSet
def get_customer_choices(customerSet):
retVal = []
for customer in customerSet:
retVal.append((customer.customer_number, '%d: %s' % (customer.customer_number, customer.company_name)))
return tuple(retVal)
class CustomerFilterTestForm(ModelForm):
class Meta:
model = Proposal
fields = ['customer_id']
def __init__(self, user=None, *args, **kwargs):
super(CustomerFilterTestForm, self).__init__(*args, **kwargs)
self.fields['customer_id'].widget = Select(choices=get_customer_choices(get_customers_by_user(user)))
# ...
views.py :
# ...
class CustomerFilterTestView(generic.UpdateView):
model = Proposal
form_class = CustomerFilterTestForm
template_name = 'proposals/customer_filter_test.html'
context_object_name = 'my_context'
success_url = "/proposals/"
def get_form_kwargs(self):
kwargs = super(CustomerFilterTestView, self).get_form_kwargs()
kwargs.update({
'user': self.request.user,
})
return kwargs
템플릿/제안/customer_filter_test.html :
{% extends "base/base.html" %}
{% block title_block %}
<title>Customer Filter Test</title>
{% endblock title_block %}
{% block header_add %}
<style>
label {
min-width: 300px;
}
</style>
{% endblock header_add %}
{% block content_body %}
<form action="" method="POST">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Save" class="btn btn-default" />
</form>
{% endblock content_body %}
나는 당신이하고 싶은 일을 정확히 이해하는지 확실하지 않지만, 당신이 최소한 사용자 정의 관리자. 특히, 현재 사용자에게 제한된 모델을 정의하려고 시도하지 말고 현재 사용자와 일치하는 객체 만 리턴하는 관리자를 만듭니다.
흠, 나는 당신의 질문을 완전히 이해하지 못합니다. 그러나 모델을 선언 할 때 할 수 없다면 사용자 객체를 "보내기"하는 객체 클래스의 우선적 인 메소드로 동일한 것을 달성 할 수 있습니다. 생성자로 시작할 수 있습니다.