2010-09-23 3 views
5

tous. Je travaille sur l'admin de mon site django et j'ai rencontré un obstacle. J'ai un modèle Entry et un modèle Related. Le modèle Related possède deux champs de clé étrangère: un pour le modèle Entry (entry) et un pour le modèle User de django (author). Le modèle Related est considéré comme un "sous-modèle" du modèle Entry, et chaque utilisateur ne peut en avoir qu'un Related par Entry. Dans l'admin, Related est édité en ligne avec Entry. Comme je l'ai, l'administrateur ne montre qu'un seul Related supplémentaire à la fois, et il remplit automatiquement le champ author avec l'utilisateur actuel:Auteur automatique dans Django administrateur

from django.contrib import models 
from django.contrib.auth.models import User 

class Entry(models.Model): 
    pass 

class Related(models.Model): 
    entry = models.ForeignKey(Entry) 
    author = models.ForeignKey(User) 
    class Meta: 
     unique_together = ('entry', 'author') 




from django.contrib import admin 

class RelatedInline(admin.StackedInline): 
    model = Related 
    exclude = ('author',) 
    max_num = 1 

class EntryAdmin(admin.ModelAdmin): 
    inlines = (RelatedInline,) 
    def save_formset(self, request, form, formset, change): 
     instances = formset.save(commit=False) 
     for instance in filter(lambda obj: isinstance(obj, Related), instances): 
      if instance.__dict__.get('author', None) is None: 
       instance.author = request.user 
       instance.save() 
     formset.save_m2m() 

Le problème est que si un utilisateur souhaite modifier une entrée qui a déjà un Related par quelqu'un, alors seulement ce champ connexe sera montré.

Si possible, je me demande si quelqu'un a des idées sur la façon dont je pourrais garder une configuration similaire à celle-ci, mais que l'administrateur affiche automatiquement related si elle existe et un formulaire vide si ce n'est pas le cas. Sauf cela, je voudrais juste me débarrasser de la ligne max_num = 1 et le remplacer par extra = 1. Bien sûr, cela signifierait qu'un formulaire "nouveau lié" montrerait même si l'utilisateur en avait déjà un pour l'entrée actuelle, donc je me demande si quelqu'un a une idée de la façon dont j'attraperais un IntegrityError possible et que je ferais savoir à l'utilisateur qu'un erreur s'est produite.

+1

en double de http://stackoverflow.com/questions/2101979/django-admin-filter-objects-for-inline-formset –

+0

Je ne suis pas sûr qu'il est. – Dave

Répondre

0

Il s'avère que c'est assez simple. Vous avez juste besoin d'ajouter une fonction queryset à votre classe RelatedInline, en précisant quelle ligne à afficher. Si le jeu de requête renvoyé a au moins un membre, le premier sera affiché. Si le jeu de requête est vide, une seule ligne vide sera affichée!

class RelatedInline(admin.StackedInline): 
    model = Related 
    exclude = ('author',) 
    max_num = 1 

    def queryset(request): 
     return Related.objects.filter(author = request.user) 
Questions connexes