Ich habe zwei Modelle:automatisch ausgefüllt Fremdschlüsselfeld Basierend auf Anwenderwahl Auswahl
class Entity(models.Model):
entity = models.CharField(primary_key=True, max_length=12)
entityDescription = models.CharField(max_length=200)
def __str__(self):
return self.entityDescription
class Action(models.Model):
entity = models.ForeignKey(Entity, on_delete=models.CASCADE, db_column='entity')
entityDescription = models.CharField(max_length=200)
action = models.CharField(max_length=50)
def __str__(self):
return '%s' % self.entity
Ich habe ein Modell Form und Modell formset, zusammen mit einem Formular Helfer für knusprige Formen:
class ActionForm(ModelForm):
class Meta:
model = Action
fields = '__all__'
def __init__(self, *args, **kwargs):
super(AlertForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.pk:
disabledFields = ['entity',
'entityDescription']
for field in disabledFields:
self.fields[field].disabled=True
else:
self.fields['entity'].blank=True
self.fields['entityDescription'] = ModelChoiceField(queryset=Entity.objects.all())
ActionFormSet = modelformset_factory(Action, extra=1, exclude=(), form=ActionForm)
class ActionFormsetHelper(FormHelper):
def __init__(self, *args, **kwargs):
super(ActionFormsetHelper, self).__init__(*args, **kwargs)
self.form_method = 'post'
self.template = 'bootstrap/table_inline_formset.html'
self.add_input(Submit("submit", "Submit"))
self.layout = Layout(
Field('entity', css_class="input", type="hidden"),
Field('entityDescription', css_class="input"),
Field('action', css_class="input")
)
ich habe einen Blick:
def actions(request):
newActions = Action.objects.filter(action='')
formset = ActionFormSet(request.POST or None, queryset=newActions)
helper = ActionFormsetHelper()
context = {'formset':formset, 'helper':helper}
if request.method == 'POST':
for form in formset:
if form.is_valid():
if form.has_changed():
obj = form.save(commit=False)
obj.entity = form.cleaned_data['entityDescription']
obj.save()
return HttpResponseRedirect('/actions')
return render(request, 'actions/actions.html', context)
Also meine gerenderte Seite etwas wie folgt aussieht:
entityDescription action
Jim Halpert [Blank Cell]
Michael Scott [Blank Cell]
[Blank Cell] [Blank Cell]
entity
ist versteckt, und entityDescription
wird durch das Entity
Modell. Wenn der Benutzer eine entityDescription auswählt, möchte ich entity
im Modell Action
autopopulieren. Logisch bedeutet das entityDescription
würde zurück zu dem Entity
Modell gehen müssen, den entsprechenden Primärschlüssel entity
finden und diesen Wert in den entity
Fremdschlüssel im Action
Modell setzen.
Mein Versuch ist in der Ansicht. Ich speicherte das Formular ohne zu committen, versuchte, entity
einen Wert zuzuweisen, und versuchte dann, das Formular zu übergeben. Dieser Versuch führt zu diesem Fehler:
Cannot assign "<Some Entity Description>": "Action.entity" must be a "Entity" instance.
Dies macht Sinn, weil ich versucht, nur die entityDescription
zuweisen entity
stattdessen die entity
zuzuweisen. Ich habe versucht, neben nur die entity
in einer hacky Weise zu erhalten, da es das erste Wort in entityDescription
ist:
obj.entity = form.cleaned_data['entityDescription'].split(' ', 1)[0]
Dies führte zu den gleichen Fehler, trotz entity
in den Fehler zu korrigieren suchen. Diese Fehler treten sowohl für die vorhandenen Modellformsatzmitglieder als auch für das neue Mitglied auf. Wie kann ich den Primärschlüssel des Modells Entity
abrufen, wenn der Benutzer einen Wert aus dem Modell Entity
auswählt? Wie weise ich dann diesen Primärschlüssel dem entsprechenden Fremdschlüsselfeld im Modell Action
zu?
Edit:
So Jim und Michael vorhandene Datensätze in Action
. Der Benutzer kann ihnen eine Aktion zuweisen. Die Leerzeile ist eine neue Aktion. Der Benutzer kann das Modell entityDescription
aus dem Modell Entity
wählen. entity
ist ein verstecktes Feld (d. H. 1 für Jim, 2 für Michael).
Wenn der Benutzer ein entityDescription
für die neue Zeile auswählt (das heißt Benutzer wählt Jim), sollte der Primärschlüssel (1) in das verborgenen entity
Feld eingegeben werden, bevor die Formen speichern.
Ein weiterer Edit:
Nach einer weiteren Untersuchung, wenn ich die Lösung in der Antwort zur Verfügung gestellt implementieren, ist das Problem hier:
obj.entity = Entity.objects.get(pk=pk)
Dies kehrt tatsächlich die entityDescription
des Entity
Modell (dh was ist definiert durch def __str__
) als den Primärschlüssel. Ich habe versucht, dies zu ändern ...
obj.entity = Entity.objects.get(pk=pk).entity
... aber dies führt in dem Primärschlüssel als String zurückgegeben wurde und nicht als Objekt. Daher kann es nicht in der Datenbank gespeichert werden. Wie würde ich diese Zeichenfolge in ein Objekt verwandeln? Mit anderen Worten, wie verwende ich die Abfragesprache, um einen Wert von einem Feld von einem Objekt eines Django-Modells zu erhalten?
Also "Entity" ist eigentlich die PK des "Entity" -Modells. Wie würde ich "entity" anstatt "entityDescription" zurückgeben? Der Benutzer wählt "entityDescription", aber ich möchte, dass "entity" in "entity" im "Action" -Modell platziert wird. –
'pk = form.cleaned_data ['entityDescription']. Split ('', 1) [0]' funktioniert für bestehende Mitglieder des Model-Formsets, aber wenn der Benutzer neue Informationen eingibt (dh BEIDE 'entityDescription' eingeben muss) und "action") funktioniert es immer noch nicht. Logischerweise muss ich 'entityDescription' verwenden, um das 'Entity'-Modell abzufragen und das tatsächliche PK-Objekt (' entity') zurückzugeben. –
können Sie 'Entity.objects.get_or_create (pk = pk)' –