2013-06-15 16 views
20

że mam formularz, który wygląda tak:dodać dane do obiektu ModelForm przed zapisaniem

forms.py

class CreateASomethingForm(ModelForm): 
    class Meta: 
     model = Something 
     fields = ['field2', 'field3', 'field4'] 

chcę mieć postać tych trzech pól. Jednak moja klasa Something ma także field1. Moje pytanie brzmi - jak dodać dane do field1, jeśli nie używam ModelForm do zbierania danych. Próbowałem zrobić coś takiego, ale to nie działa i jestem pewien na właściwym sposobem rozwiązania to:

views.py

def create_something_view(request): 
    if (request.method == 'POST'): 
     # Create an object of the form based on POST data 
     obj = CreateASomething(request.POST) 
     # ** Add data into the blank field1 ** (Throwing an error) 
     obj['field1'] = request.user 
     # ... validate, save, then redirect 

Błąd zgłaszany jest:

TypeError: 'CreateAClassForm' object does not support item assignment 

Jaki jest prawidłowy sposób przypisania danych do obiektu przed zapisaniem?

Odpowiedz

41
form = CreateASomething(request.POST) 
if form.is_valid(): 
    obj = form.save(commit=False) 
    obj.field1 = request.user 
    obj.save() 
+0

Thank You - głupi błąd na mój koniec przy użyciu wywołania dostępu do listy, aby uzyskać atrybut obiektu. – Joker

+2

Aby uzyskać widoki klasowe, możesz również [zastąpić metodę form_valid] (https://docs.djangoproject.com/en/1.5/topics/class-based-views/generic-editing/#basic-forms), aby dodać rodzaj informacji, następnie wywołaj 'super (MyView, self) .form_valid (form)', aby osiągnąć ten sam efekt. –

+0

Czy istnieje sposób nadpisania metody zapisywania formularza w celu osiągnięcia tego samego? – jvannistelrooy

6

Czasami pole może być wymagane, co oznacza, że ​​nie można go pominąć form.is_valid(). W takim przypadku można przekazać do formularza obiekt dict zawierający wszystkie pola.

if request.method == 'POST': 
     data = { 
     'fields1': request.user, 
     'fields2': additional_data, 
     } 
     form = CreateASomethingForm(data) 

    if form.is_valid(): 
     form.commit(save) 
0

Tutaj jest bardziej odpowiedni sposób, aby dodać dane szczególnie używane podczas testów:

najpierw przekonwertować istniejący wpis do słownika z funkcją model_to_dict

from django.forms.models import model_to_dict 

... 

valid_data = model_to_dict(entry) 

Następnie dodać nowe dane do ten słownik

valid_data['finish_time'] = '18:44' 

To działa lepiej niż ustawienie wartości w postaci

update_form.finish_time = '18:44' 

Tworzenie formularza z ważnych danych i instancji

update_form = UserEntryForm(valid_data, instance=entry) 

robić żadnych twierdzeń można wymagać:

self.assertTrue(update_form.is_valid()) 
entry = update_form.save() 
self.assertEqual(
    entry.status, 
    1 
)