Django ModelForm nie zapisuje danych do bazy danych
Początkujący Django ma tutaj wiele problemów z działaniem formularzy. Tak, pracowałem nad samouczkiem i często przeglądałem sieć - mam mieszankę tego, co znajduję tutaj i na innych stronach. Używam Pythona 2.7 i Django 1.5. (chociaż oficjalna dokumentacja jest obszerna, zakłada ona, że większość z nich już wiesz - niezbyt dobra jako referencja dla początkujących, a nawet zaawansowany tutorial)
Próbuję utworzyć formularz dla „rozszerzonych” danych użytkownika - np. nazwa firmy, adres ulicy itp., ale dane formularza nie są zapisywane w bazie danych.
Początkowo próbowałem stworzyć model rozszerzający standardUser
model, ale zrezygnowałem z tego - zbyt wiele wymagało modyfikacji i nabierało rozpędu, co było daleko poza mną na tym etapie. Zamiast tego stworzyłem nowy model o nazwieUserProfile
:
class UserProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, unique=True)
company = models.CharField(max_length=50, blank=True)
address1 = models.CharField(max_length=50, blank=True)
address2 = models.CharField(max_length=50, blank=True)
city = models.CharField(max_length=20, blank=True)
region = models.CharField(max_length=20, blank=True)
postcode = models.CharField(max_length=10, blank=True)
country = models.CharField(max_length=20, blank=True)
phone = models.CharField(max_length=30, blank = True)
Widziałem różne odniesienia online, czy powinienem połączyć się z modelem użytkownika za pomocąForeignKey
(jak wyżej) lub z OneToOne.
Próbuję użyć ModelForm (zachowaj prostotę dla tego, co powinno być prostą formą). Oto moje formula.py
from django.forms import ModelForm
from .models import UserProfile
class UserDetailsForm(ModelForm):
class Meta:
model = UserProfile
fields = ['company','address1','address2','city','region', 'postcode','country','phone']
Oto mój pogląd:
def UserDetailsView(request):
#f = 0
if request.method == 'POST':
f = UserDetailsForm(request.POST, instance = request.user)
if f.is_valid():
f.save()
else:
f = UserDetailsForm(request.POST , instance = request.user)
print "UserDetails objects: ", (UserProfile.objects.all())
return render_to_response('plagweb/console/profile.html',
{ 'form': f},
context_instance=RequestContext(request))
(tak, istnieje niespójność w UserProfile vs UserDetail - jest to produkt z całego mojego hakowania i zostanie naprawiony, gdy tylko zadziała)
Pokaz diagnostycznyf.is_valid()
wracając Prawda. Podobnie pokazuje diagnostykaUserProfile.objects.all()
jako pusty. Próbowałem tego w powyższym widoku po save (), a także w konsoli Django.
Oto mój szablon:
<form method="POST" action="">
<table>{{ form }}</table>
<input type="submit" value="Update" />
{% csrf_token %}
</form>
W tej chwili głównym problemem jest to, że dane formularza nie są zapisywane w bazie danych. Nie wiem, czy czyta się jeszcze, czy nie (gdy już mam dane w bazie danych ...)
Jedna myśl jest taka, żeUser
związek może powodować problem?
Dodatki, kontynuacja przydatnego komentarza / pomocy Daniela Rosemana:
Teraz formularz jest zapisywany poprawnie (potwierdzony diagnostyką i sprawdzaniem w wierszu poleceń. Jednak po powrocie do formularza nie wyświetla istniejących danych. Wyświetlany jest formularz z pustymi polami danych. O ile wiem, ja ” m poprawnie przekazuje dane instancji.
Czy istnieje ustawienie ModelForm, które należy zmienić?
Oto zmodyfikowany widok:
def UserDetailsView(request):
#print "request co:", request.user.profile.company
f = UserDetailsForm(request.POST, instance = request.user.profile )
if request.method == 'POST':
if f.is_valid():
profile = f.save(commit=False)
profile.user = request.user
profile.save()
return render_to_response('plagweb/console/profile.html',
{ 'form': f},
context_instance=RequestContext(request))
Diagnostyka to pokazujerequest.user.profile
jest poprawnie ustawiony (konkretnie pole firmowe). Jednak formularz jest wyświetlany z pustymi polami. Źródło HTML również nie pokazuje żadnych wartości danych. Jako dodatkową kontrolę wypróbowałem także niektóre diagnostyki szablonów:
<table border='1'>
{% for field in form%}
<tr>
<td>{{field.label}}</td>
<td>{{field.value}}</td>
</tr>
{% endfor%}
</table>
Wyświetla poprawnie etykiety pól, ale wszystkie wartości są zgłaszane jakoNone
.
Dla kompletności pole użytkownika UserProfile jest teraz zdefiniowane jakouser = models.OneToOneField(settings.AUTH_USER_MODEL)
a wyrażenie lambda User.profile jest niezmienione.