Comment définir la valeur d'un champ (qui est pertinent pour la forme, mais pas directement basé sur le même modèle) sur un formulaire (modèle) lorsqu'il est affiché dans l'admin?Valeur d'affichage Django du champ supplémentaire dans le modèle
est ici une version simplifiée de ce que je (mon application réelle/modèle/etc est plus compliqué):
- A
building
a beaucouproom
s - A
room
a beaucoup de morceaux deequipment
Modèles:
#spaces/models.py
from django.db import models
class Building(models.Model):
name=models.CharField(max_length=32)
def __unicode__(self):
return self.name
class Room(models.Model):
number=models.CharField(max_length=8)
building=models.ForeignKey(Building)
def __unicode__(self):
return self.number
class Equipment(models.Model):
tech = models.CharField(max_length=64)
room = models.ForeignKey(Room)
def __unicode__(self):
return self.tech
Lors de l'ajout ou de la modification d'un équipement, il serait bon de pouvoir limiter les choix room
(par bâtiment). Ce que je peux faire: J'ajoute un champ building
au ModelForm, puis, comme il est modifié par l'utilisateur, un bit de JQuery dans le fichier modèle met à jour dynamiquement la liste des room
s. La partie admin.py
ressemble:
#spaces/admin.py
from demo.spaces.models import Building, Room, Equipment
from django.contrib import admin
from django import forms
class EquipmentForm(forms.ModelForm):
class Meta:
model = Equipment
building = forms.ModelChoiceField(Building.objects)
class EquipmentAdmin(admin.ModelAdmin):
form = EquipmentForm
admin.site.register(Equipment, EquipmentAdmin)
admin.site.register(Building)
admin.site.register(Room)
Lorsque vous ajoutez un nouveau morceau de equipment
, tout cela fonctionne bien - mon code JQuery affiche -----
jusqu'à ce qu'un bâtiment est sélectionné, à quel point le menu déroulant du champ room
est activé et rempli avec les room
appropriés pour ce bâtiment.
Le problème est: lors de l'affichage d'une pièce d'équipement existant (demo.com/admin/spaces/equipment/12/
) ou si le formulaire d'ajout ne valide pas, le champ Room
affiche correctement la room
--mais le champ building
est effacé. La valeur de clé étrangère existe dans l'instance de formulaire et l'administrateur prend automagiquement en charge la définition du champ room
à cette valeur, mais la valeur du champ building
doit être définie par moi.
Je peux obtenir la valeur sans problème, car il est facile dans la initialisation du formulaire pour vérifier qu'il est une instance, puis traversant de nouveau jusqu'à obtenir la valeur:
def __init__(self, *args, **kwargs):
super(EquipmentForm, self).__init__(*args, **kwargs)
if 'instance' in kwargs:
building_value = kwargs['instance'].room.building
Mais que fais-je avec cette valeur pour que le champ l'affiche? La seule chose que je n'ai pas encore essayée est d'ajouter plus de code dans mon template pour utiliser Jquery pour obtenir la valeur et la définir à la fin, mais je préfère ne pas avoir le javascript dans la page la valeur, car il semble que quelque chose devrait être fait lorsque le formulaire est rendu ...
Des pensées? Merci pour votre aide!
je serais beaucoup mieux en mesure de limiter les choix pour le bâtiment, depuis A) Il y aura B) Je veux utiliser la même procédure pour limiter d'autres clés étrangères dans d'autres endroits. – mightyhal
L'argument field.initial n'aidera pas, puisque la valeur que je veux définir pour le bâtiment est dynamique (dépend de l'instance). Form.initial semble prometteur, en définissant self.initial ['building'] dans __init__, et un print self.initial crache un dictionnaire de tous les champs et leurs valeurs ... mais quand il rend, il ne définit pas la valeur pour la construction (bien que cela ressemble à ce qu'il devrait) – mightyhal