4 Stimmen

Daten aus einem Formular mit benutzerdefiniertem Fremdschlüsselfeld in Django speichern

Ich habe die folgenden Modellklassen:

class ContactPerson(models.Model):            
    name = models.CharField(max_length=30)

    def __unicode__(self):
        return self.name

class Appartment(models.Model):
    contact_person = models.ForeignKey(ContactPerson)

Problem: In der Vorlagendatei möchte ich, dass ein Benutzer den Namen des Ansprechpartners ausfüllt, also überschreibe ich das Feld contact_person wie folgt:

class AppartmentSellForm(ModelForm):
    contact_person = forms.CharField(max_length=30)

    class Meta:
        model = Appartment

In meiner Ansichtsfunktion tue ich das Folgende, um Daten aus einem übermittelten Formular zu speichern:

def appartment_submit(request):
    if request.method == "POST":
        form = AppartmentSellForm(request.POST)
        if form.is_valid():
            appartment = form.save(commit=False) # ERROR HERE
            cp = models.ContactPerson(name=form.cleaned_data['contact_person'])
            appartment.contact_person = cp
            appartment.save()
            form.save();
            return HttpResponseRedirect('/sell/')
    else:
        form = AppartmentSellForm()
    return render_to_response('sell_appartment_form.html', {'form' : form})

Fehlermeldung :

#ValueError at /sell/sell_appartment/appartment_submit/

Cannot assign "u'blabla'": "Appartment.contact_person" must be a "ContactPerson" instance.**

Ich verwende SQLite und django Version 1.1.1

Frage: Wie lässt sich dieses Problem lösen?

1voto

adamnfish Punkte 10425

Ich denke, der Code, den Sie in Ihre Ansicht setzen, wäre besser für die Validierung des ModelForm geeignet.

Überschreiben Sie das Modellformular der clean_contact_person Methode und fügen Sie dort den Code ein, der a) prüft, ob der Name gültig ist, und wenn ja, b) den Wert des Formularfelds auf die tatsächliche ContactPerson-Instanz setzt.

Etwa so: (aus dem Stegreif)

class AppartmentSellForm(ModelForm):
    contact_person = forms.CharField(max_length=30)

    class Meta:
        model = Appartment

    def clean_contact_person(self):
        name = self.cleaned_data['contact_person']
        # check the name if you need to
        try:
            # maybe check if it already exists?
            person = models.ContactPerson.objects.get(name=name)
        except ContactPerson.DoesNotExist:
            person = models.ContactPerson(name=name)
            # you probably only want to save this when the form is saved (in the view)
        return person

Ihre Ansicht muss möglicherweise noch die commit=False (da Sie den ContactPerson-Datensatz speichern müssen). Sie können dies mit der Methode save_m2m Methode.

Es gibt mehr Informationen über save_m2m sur die ModelForm-Dokumentation und Informationen über die Reinigung von Feldern in die Validierungsdokumentation .

Ich hoffe, das hilft, viel Glück!

0voto

Roshan Mathews Punkte 5552

Sie können eine der folgenden Möglichkeiten nutzen:

  1. Versuchen Sie exclude die contact_person Feld, wie erwähnt in Punkt 3 hier drüben
  2. oder Sie könnten das Feld einfach nicht in Ihrer ModelForm und Django wird es als eine ModelChoiceField Es sei denn, Sie wollen, dass die Leute einen Namen eintippen, anstatt eine Dropdown-Liste zur Auswahl zu haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X