2016-03-21 8 views
0

Ich bin bei der Verwendung eines ModelForm in eine Sackgasse geraten.Problem mit ModelForm und verwandten Objekten

Ich bin extending the User model das kommt mit Django, und ich benutze auch eine ModelForm, so dass der Benutzer es bearbeiten kann.

Nach dem gleichen Beispiel in der Dokumentation, würde ich diesen Code haben.

models.py

class Employee(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    # In this case, department is optional, so I have set 'blank' and 'null' to True. 
    department = models.CharField(max_length=100, blank=True, null=True) 

forms.py

class DepartmentForm(ModelForm): 
    class Meta: 
     model = Employee 
     fields = ['department',] 

Das Problem kommt auf die Ansicht. Ich habe festgestellt, dass ich eine Instanz des Modells an das Formular übergeben muss, damit die save() - Funktion funktioniert, ohne sie anpassen zu müssen, aber natürlich wurde user.employee noch nicht erstellt, daher wird ein Fehler ausgegeben.

views.py

def DepartmentView(request): 
    # Here is the issue. 
    department = request.user.employee 
    if request.method == 'POST': 
     # I need to pass the instance here. 
     form = DepartmentForm(request.POST, instance=department) 
     if form.is_valid(): 
      form.save() 
    else: 
     # And also here so it autocompletes the form. 
     form = DepartmentForm(instance=department) 
    return render(request, 'employee.html', {'form': form}) 

Es funktioniert, wenn ich durch die Schale manuell einen Wert in den user.employee.department und dann die Seite neu zu laden, sonst ist der Fehler wie folgt.

RelatedObjectDoesNotExist at [something] 
User has no employee. 

Oder so ähnlich ... Es tut mir Leid, ich versuche nicht den obigen Code so dass der Fehler ein wenig anders sein könnte, aber das Konzept ist genau das gleiche.

Es tut mir auch leid, wenn dies zuvor gefragt wurde. Ich habe eine Google-Suche durchgeführt und konnte keine Antwort auf dieses Problem finden.

+0

Beachten Sie, dass es normalerweise nicht notwendig ist, für ein 'CharField'' null = True' zu ​​haben. Wenn Sie einfach "leer = Wahr" haben, ist das Feld optional und speichert die leere Zeichenfolge "", wenn der Wert nicht angegeben wird. – Alasdair

Antwort

0

Sie könnten get_or_create verwenden, um den Mitarbeiter aus der db abzurufen, oder erstellen Sie ihn, wenn er nicht existiert.

department, created = Employee.objects.get_or_create(user=request_or_user, department='') 
if request.method == 'POST': 
    form = DepartmentForm(request.POST, instance=department) 
    ... 

Eine andere Option besteht darin, ein Signal zu verwenden, damit das zugehörige Modell erstellt wird, wenn der Benutzer erstellt wird. Dann können Sie davon ausgehen, dass der Mitarbeiter bereits existiert, und Sie können request.user.employee anstelle von get_or_create verwenden.

+0

Danke, 'get_or_create' scheint meine beste Wette zu sein. Der Grund, warum ich 'null = True' in das Modell einfügte, ist, weil ich ohne ihn eine Menge 'IntegrityError'-Fehler erhalte, wenn das Feld leer ist, selbst wenn 'get_or_create' verwendet wird. –

+0

Ich bin überrascht, dass Sie Integritätsfehler erhalten, es sei denn, Sie haben 'unique = True' für das Feld festgelegt. Sie könnten versuchen, 'department = ''' beim Erstellen der Instanz zu setzen. – Alasdair

+0

Ich würde mich nicht viel darum kümmern, es funktioniert gut, wenn Sie 'null = True' und' get_or_create' verwenden. –

Verwandte Themen