Modèle de limiter les choix d'={utilisateur: utilisateur}
je suis allé à toute la documentation, aussi je suis allé à la chaîne IRC (BTW une grande communauté) et ils m'ont dit que ce n'est pas possible de créer un modèle et de limiter les choix dans un domaine où l '"utilisateur courant" est dans une clé étrangère. Je vais essayer d'expliquer cela avec un exemple:
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()
bien sûr que le code ne fonctionne pas parce qu'il n'y a pas d'objet 'user', mais c'était mon idée et j'essayais d'envoyer l'objet 'user' au modèle pour limiter les choix où l'utilisateur actuel a des projets, je ne veux pas voir des projets dans lesquels je ne suis pas.
je vous Remercie beaucoup si vous pouvez m'aider ou me donner des conseils, je ne veux pas vous écrire tout ce que l'application, juste un conseil, la façon de traiter avec que. J'ai 2 jours avec ça dans la tête et je n'arrive pas à le comprendre: (
UPDATE : la solution est ici: http://collingrady.wordpress.com/2008/07/24/useful-form-tricks-in-django / envoi request.user
à un modèle.
6 réponses
utilisez threadlocals si vous voulez obtenir l'utilisateur current qui édite ce modèle. Threadlocals middleware met l'utilisateur courant dans la variable de l'ensemble du processus. Prenez ce 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)
Vérifiez la documentation sur l'utilisation des classes middleware. Puis n'importe où dans le code vous pouvez appeler
user = threadlocals.get_current_user
modèle lui-même ne sait rien sur l'utilisateur actuel, mais vous pouvez donner à cet utilisateur en vue de la forme qui exploite les objets modèles (et dans la forme réinitialiser choices
pour le champ nécessaire).
Si vous avez besoin de ce sur admin du site - vous pouvez essayer raw_id_admin
avec django-granular-permissions
( http://code.google.com/p/django-granular-permissions/ mais je ne pouvais pas rapidement le faire fonctionner sur mon django, mais il semble être assez fraîche pour la 1.0...).
enfin, si vous avez fortement besoin d'une selectbox dans admin - alors vous aurez besoin de hacker django.contrib.admin
lui-même.
cette limitation des choix à l'utilisateur courant est une sorte de validation qui doit se produire dynamiquement dans le cycle de requête, et non dans la définition de modèle statique.
en d'autres termes: au point où vous créez une instance de ce modèle vous serez dans une vue et à ce point vous aurez accès à l'utilisateur courant et pouvez limiter les choix.
alors vous avez juste besoin d'un modèle personnalisé pour passer dans le demande.utilisateur pour, voir l'exemple ici: 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
alors à votre avis:
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})
Je ne suis pas sûr que je comprenne parfaitement ce que vous voulez faire, mais je pense qu'il y a de bonnes chances que vous obtiendrez au moins une partie de la manière là-bas en utilisant un custom Manager . En particulier, n'essayez pas de définir vos modèles avec des restrictions à l'utilisateur courant, mais créez un gestionnaire qui ne renvoie que les objets qui correspondent à l'utilisateur courant.
Hmmm, Je ne comprends pas bien votre question. Mais si vous ne pouvez pas le faire quand vous déclarez le modèle peut-être que vous pouvez obtenir la même chose avec les méthodes de dépassement de la classe d'objets où vous "envoyez" l'objet utilisateur, peut-être commencer avec le constructeur.