Comment puis-je filtrer ForeignKey choix dans un Django ModelForm?
Dire que j'ai la suite dans ma models.py
:
class Company(models.Model):
name = ...
class Rate(models.Model):
company = models.ForeignKey(Company)
name = ...
class Client(models.Model):
name = ...
company = models.ForeignKey(Company)
base_rate = models.ForeignKey(Rate)
I. e. il y a plusieurs Companies
, ayant chacun une gamme de Rates
et Clients
. Chaque Client
devrait avoir une base Rate
qui est choisi à partir de celle du parent Company's Rates
, pas un autre Company's Rates
.
Lors de la création d'un formulaire pour l'ajout d'un Client
, je voudrais enlever la Company
choix (comme cela a déjà été sélectionné en passant par un "Client" sur le bouton de Company
page) et de limiter le Rate
choix que Company
ainsi.
Comment puis-je aller à ce sujet dans Django 1.0?
Mon forms.py
fichier est juste réutilisable à l'instant:
from models import *
from django.forms import ModelForm
class ClientForm(ModelForm):
class Meta:
model = Client
Et la views.py
est également de base:
from django.shortcuts import render_to_response, get_object_or_404
from models import *
from forms import *
def addclient(request, company_id):
the_company = get_object_or_404(Company, id=company_id)
if request.POST:
form = ClientForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(the_company.get_clients_url())
else:
form = ClientForm()
return render_to_response('addclient.html', {'form': form, 'the_company':the_company})
Dans Django 0.96 j'ai été en mesure de pirater ce en en faisant quelque chose comme ce qui suit avant de rendre le modèle:
manipulator.fields[0].choices = [(r.id,r.name) for r in Rate.objects.filter(company_id=the_company.id)]
ForeignKey.limit_choices_to
semble prometteur, mais je ne sais pas comment passer en the_company.id
et je ne suis pas clair si ce sera de travailler à l'extérieur de l'interface d'administration de toute façon.
Grâce. (Cela semble assez simple demande, mais si je dois redessiner quelque chose je suis ouvert aux suggestions.)
- Merci pour l'astuce de "limit_choices_to". Elle ne résout pas votre question, mais la mienne 🙂 Docs: docs.djangoproject.com/en/dev/ref/models/fields/...
Vous devez vous connecter pour publier un commentaire.
ForeignKey est représenté par django.les formulaires.ModelChoiceField, qui est un ChoiceField dont les choix sont un modèle de QuerySet. Consultez la référence pour ModelChoiceField.
Oui, fournir un QuerySet du champ
queryset
attribut. Dépend de la façon dont votre formulaire est construit. Si vous construisez une forme explicite, vous aurez champs nommés directement.Si vous prenez le défaut ModelForm objet,
form.fields["rate"].queryset = ...
Cela est fait de manière explicite dans la vue. Pas de piratage autour de.
__init__
méthode?__init__
méthode remplit le Formulaire de données à des fins de validation, généralement à partir derequest.POST
En plus de S. Lott réponse et que becomingGuru mentionné dans les commentaires, il est possible d'ajouter le queryset filtres en remplaçant la
ModelForm.__init__
fonction. (Cela pourrait facilement s'appliquer aux formes régulières) il peut aider à la réutilisation et maintient le point de vue de la fonction en ordre.Cela peut être utile pour réutiliser dire si vous avez des filtres courants nécessaires sur de nombreux modèles (normalement je déclare une Forme abstraite de la classe). E. g.
Que je suis juste en retraitant Django blog matériau avec lequel il y a beaucoup de bons là-bas.
C'est simple, et fonctionne avec Django 1.4:
Vous n'avez pas besoin de le spécifier dans une classe de formulaire, mais il peut le faire directement dans le ModelAdmin, comme Django comprend déjà cette méthode intégrée sur le ModelAdmin (à partir de la documentation):
Un même niftier façon de le faire (par exemple dans la création d'un front-end de l'interface d'administration que les utilisateurs peuvent accéder) est une classe de la ModelAdmin et ensuite modifier les méthodes ci-dessous. Le résultat net est une interface utilisateur qui leur montre que le contenu qui est lié à eux, tout en vous permettant de vous (super-utilisateur) pour tout voir.
J'ai remplacé les quatre méthodes, les deux premiers font qu'il est impossible pour un utilisateur de supprimer quoi que ce soit, et il supprime également les boutons de suppression de l'admin du site.
La troisième remplacer les filtres de la requête qui contient une référence à (dans l'exemple "utilisateur" ou "porc-épic" (tout comme une illustration).
La dernière remplacer les filtres tout foreignkey champ dans le modèle pour filtrer les choix disponibles de même que la base queryset.
De cette façon, vous pouvez présenter un facile à gérer face à l'avant de l'admin du site qui permet aux utilisateurs de jouer avec leurs propres objets, et vous n'avez pas à vous rappeler de taper dans le ModelAdmin filtres nous avons parlé ci-dessus.
supprimer 'delete': les boutons de
empêche de supprimer l'autorisation
filtres des objets qui peuvent être consultés sur le site d'administration:
filtres de choix pour tous les foreignkey champs sur le site d'administration:
Faire cela avec une vue générique, comme CreateView...
la partie la plus importante de cette...
lire mon post ici
Si vous n'avez pas créé le formulaire et que vous souhaitez modifier le queryset que vous pouvez faire:
C'est assez utile lors de l'utilisation de générique point de vue!
Donc, j'ai vraiment essayé de comprendre, mais il semble que Django n'est toujours pas à le faire très simple. Je ne suis pas du tout bête, mais je ne peux pas les voir du tout (un peu) la solution la plus simple.
Je trouve qu'il est généralement assez laid d'avoir à remplacer l'Admin vues pour ce genre de chose, et chaque exemple que je trouve jamais s'applique pleinement à l'Admin vues.
C'est comme une circonstance commune avec les modèles que je fais, que je trouve consternant qu'il n'y a pas de solution évidente à ce...
J'ai ces classes:
Cela crée un problème lors de la configuration de l'Admin pour la Société, parce qu'il a des inlines pour les deux Contrat et l'Emplacement, et le Contrat du m2m options pour l'Emplacement ne sont pas correctement filtrée selon la Compagnie que vous êtes en train d'éditer.
En bref, j'aurais besoin d'une option d'administration pour faire quelque chose comme ceci:
En fin de compte, je m'en foutrais si le processus de filtrage a été placé sur la base CompanyAdmin, ou si elle était placée sur la ContractInline. (En le plaçant sur la ligne a plus de sens, mais elle rend difficile la référence au Contrat de base comme "moi".)
Est qu'il ya quelqu'un qui sait de quelque chose d'aussi simple que ce mal nécessaire raccourci? Lorsque j'ai fait PHP admins pour ce genre de chose, ce qui était considéré comme une fonctionnalité de base! En fait, il a toujours été automatique, et a dû être désactivé si vous n'avez vraiment pas envie!
Plus de voie publique est en appelant get_form dans l'Admin classes. Il fonctionne également pour les non-champs de base de données aussi. Par exemple ici, j'ai un champ appelé "_terminal_list' sur le formulaire qui peut être utilisé dans des cas particuliers pour le choix de plusieurs terminaux éléments de get_list(demande), le filtrage en fonction de la demande.utilisateur: