Modelo limit_choices_to = {‘usuario’: usuario}

Fui a toda la documentación, también fui al canal de IRC (BTW, una gran comunidad) y me dijeron que no es posible crear un modelo y limitar las opciones en un campo donde el “usuario actual” está en una ForeignKey. Trataré de explicar esto con un ejemplo:

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

Por supuesto, ese código no funciona porque no hay un objeto ‘usuario’, pero esa fue mi idea y estaba tratando de enviar el objeto ‘usuario’ al modelo para limitar las opciones en las que el usuario actual tiene proyectos. No quiero ver proyectos donde no estoy.

Muchas gracias si puedes ayudarme o darme algún consejo, no quiero que escribas toda la aplicación, solo un consejo sobre cómo lidiar con eso. Tengo 2 días con esto en mi cabeza y no puedo entenderlo 🙁

ACTUALIZACIÓN : La solución está aquí: http://collingrady.wordpress.com/2008/07/24/useful-form-tricks-in-django/ enviando request.user a un modelo.

Use threadlocals si desea obtener el usuario actual que edita este modelo. El middleware Thloclocals coloca al usuario actual en una variable de todo el proceso. Toma este 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) 

Consulte la documentación sobre cómo utilizar las clases de middleware. Entonces en cualquier lugar del código puedes llamar

 user = threadlocals.get_current_user 

El modelo en sí mismo no sabe nada sobre el usuario actual, pero puede darle a este usuario una vista del formulario que opera los objetos de modelos (y en las choices restablecimiento de formulario para el campo necesario).

Si necesita esto en el sitio de administración, puede probar raw_id_admin junto con django-granular-permissions ( http://code.google.com/p/django-granular-permissions/ pero no pude hacerlo funcionar rápidamente en mi django pero parece ser lo suficientemente fresco para 1.0 así que …).

Por último, si necesita mucho un cuadro de selección en el administrador, deberá piratear django.contrib.admin .

Esta limitación de opciones para el usuario actual es un tipo de validación que debe ocurrir dinámicamente en el ciclo de solicitud, no en la definición del Modelo estático.

En otras palabras: en el punto en el que está creando una instancia de este modelo, estará en una Vista y en ese punto tendrá acceso al usuario actual y podrá limitar las opciones.

Entonces solo necesita un ModelForm personalizado para pasar el request.user a, vea el ejemplo aquí: 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 

entonces en su opinión:

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

Aquí está el CookBook Threadlocals y el usuario

Usando Vistas genéricas basadas en clases en Django 1.8.x / Python 2.7.x, esto es lo que mis colegas y yo creamos:

En models.py:

 # ... class Proposal(models.Model): # ... # Soft foreign key reference to customer customer_id = models.PositiveIntegerField() # ... 

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

En 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 

En plantillas / propuestas / customer_filter_test.html:

 {% extends "base/base.html" %} {% block title_block %} Customer Filter Test {% endblock title_block %} {% block header_add %}  {% endblock header_add %} {% block content_body %} 
{% csrf_token %} {{ form.as_table }}
{% endblock content_body %}

No estoy seguro de entender exactamente lo que quiere hacer, pero creo que hay una buena probabilidad de que llegue al menos parte del camino usando un Administrador personalizado . En particular, no intente definir sus modelos con restricciones para el usuario actual, sino cree un administrador que solo devuelva objetos que coincidan con el usuario actual.

Hmmm, no entiendo completamente tu pregunta. Pero si no puede hacerlo cuando declara el modelo, tal vez pueda lograr lo mismo con métodos de reemplazo de la clase de objetos a los que “envía” el objeto de usuario, tal vez comience con el constructor.