2010-04-23 4 views
1

Je suis nouveau sur django, alors n'hésitez pas à me dire si je ne le fais pas correctement. J'essaie de créer un système de commande django. Mon modèle de commande:Comment faire un affichage personnalisé et auto-select dans le champ django admin multi-select?

class Order(models.Model): 
    ordered_by = models.ForeignKey(User, limit_choices_to = {'groups__name': "Managers", 'is_active': 1}) 

dans mon admin tout utilisateur peut entrer dans un ordre, mais ordered_by doit être quelqu'un dans le groupe « managers » (ce qui est le comportement que je veux).

Maintenant, si l'utilisateur connecté se trouve être un gestionnaire, je veux qu'il remplisse automatiquement le champ avec cet utilisateur connecté. J'ai accompli cela par:

class OrderAdmin(admin.ModelAdmin): 
    def formfield_for_foreignkey(self, db_field, request, **kwargs): 
    if db_field.name == "ordered_by": 
     if request.user in User.objects.filter(groups__name='Managers', is_active=1): 
      kwargs["initial"] = request.user.id 
     kwargs["empty_label"] = "-------------" 
     return db_field.formfield(**kwargs) 
    return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) 

Cela fonctionne aussi, mais l'administrateur met le nom d'utilisateur que l'affichage de la boîte de sélection par défaut. Ce serait bien d'avoir le vrai nom de l'utilisateur. J'ai pu le faire avec ceci:

class UserModelMultipleChoiceField(forms.ModelMultipleChoiceField): 
    def label_from_instance(self, obj): 
     return obj.first_name + " " + obj.last_name 
class OrderForm(forms.ModelForm): 
    ordered_by = UserModelChoiceField(queryset=User.objects.all().filter(groups__name='Managers', is_active=1)) 

class OrderAdmin(admin.ModelAdmin): 
    form = OrderForm 

Mon problème: Je ne peux pas les deux. Si je mets dans la fonction formfield_for_foreignkey et ajoute form = OrderForm pour utiliser mon "UserModelChoiceField" personnalisé, il met l'affichage du nom gentil mais il ne sélectionnera pas l'utilisateur actuellement connecté. Je suis nouveau à cela, mais je suppose que lorsque j'utilise UserModelChoiceField, il "efface" l'information transmise via formfield_for_foreignkey. Ai-je besoin d'utiliser la fonction super() pour transmettre cette information? ou quelque chose de complètement différent?

Répondre

0

Éliminer complètement la sous-classe ModelChoiceField/ModelMultipleChoiceField et utiliser la méthode formfield_for_foreignkey. L'argument request n'est pas disponible dans la sous-classe et vous ne pouvez donc pas obtenir l'utilisateur actuel. Ensuite, utilisez la méthode label_from_instance à formfield_for_foreignkey. Vous pouvez l'écrire vous-même, mais un extrait de Django robuste est disponible au http://djangosnippets.org/snippets/1642/. Juste sous-classe la classe de cet extrait. Vous pouvez le placer dans un fichier différent et l'importer, ou l'écrire au-dessus de la classe OrderAdmin en tant que OrderAdmin(NiceUserModelAdmin).

Enfin, réécrivez la méthode formfield_for_foreignkey pour prendre le kwargs["initial"] = request.user.id en dehors de l'instruction if. Je ne pense pas que ce soit nécessaire et j'ai aussi eu du mal à le faire fonctionner de cette façon.

# admin.py 

from django.contrib import admin 
from django.contrib.auth.models import User 
from (...) import Order 

class NiceUserModelAdmin(admin.ModelAdmin): 
    # ... 

class OrderAdmin(NiceUserModelAdmin): 
    # ... 
    def formfield_for_foreignkey(self, db_field, request, **kwargs): 
     kwargs["initial"] = request.user.id 
     if db_field.name == "ordered_by": 
      kwargs["empty_label"] = "-------------" 
      return db_field.formfield(**kwargs) 
     return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) 
Questions connexes