2011-01-12 9 views
36

Prawdopodobnie pytanie dla początkujących, więc proszę o zachowanie mnie.Jak zaktualizować obiekt z formularza edycji w Django?

Mam formularz Django, który edytuje określoną instancję modelu. Aby wiedzieć, który obiekt jest edytowany, mam ukryte pole zawierające identyfikator obiektu wraz z adresem URL zawierającym identyfikator.

Pierwsze pytanie: Czy identyfikacja obiektu w ukrytym polu jest właściwa?

Moja (prawdopodobnie bezpodstawna) troska o posiadanie go tylko jako części adresu URL jest taka, że ​​ktoś mógłby następnie otworzyć stronę o jednym id obiektu, przesłać formularz do innego, a ten obiekt zostanie nadpisany. Dlatego próbuję użyć ukrytego pola.

Problem z przechowywaniem id w ukrytym polu polega na tym, że po zatwierdzeniu formularza Django skarży się, że obiekt nie ma unikalnego identyfikatora (oczywiście).

Drugie pytanie: Jeśli pole jest unikalna część formularza, w jaki sposób można powiedzieć Django zignorować fakt, że klucz już istnieje, w celu aktualizacji obiekt?

+0

Czy możesz mi pokazać swoją postać? PS: Tak, bez zabezpieczeń (uprawnienia), '/ edit/{{id}} /' byłoby dostępne dla każdego i niebezpieczne. –

+1

Cóż, mam zabezpieczenia, takie jak sprawdzanie, czy obiekt należy do zalogowanego użytkownika - ale nawet wtedy ten użytkownik (z nieznanych mi powodów) może edytować niezamierzony obiekt. –

Odpowiedz

63

Dlaczego po prostu nie użyjesz ModelForm?

# forms.py 
# ... 
class MyForm(forms.ModelForm): 
    class Meta: 
     model = MyModel 

# views.py 
# ...  
def my_view(request, id): 
    instance = get_object_or_404(MyModel, id=id) 
    form = MyForm(request.POST or None, instance=instance) 
    if form.is_valid(): 
     form.save() 
     return redirect('next_view') 
    return render(request, 'my_template.html', {'form': form}) 
+3

Fantastyczna - to ten parametr "instancji", którego mi brakowało. Wydaje się, że wielki światowy serwis internetowy pozbawiony jest samouczków dotyczących edycji obiektów za pomocą formularzy w Django. –

+0

To jest właściwa droga, ale nie odpowiada: jak twój pogląd dostał argument "id"? mapowanie adresu URL lub ukryte pole są jedynymi sposobami? –

+1

Tak, i nie ma w tym nic złego. Prawdopodobnie żonglujesz sesjami, ale naprawdę nie widzę sensu. Jeśli identyfikator zostanie przekazany do wyświetlenia, wówczas widok może określić, czy użytkownik ma uprawnienia do aktualizacji obiektu, a programista powinien wymusić tę kontrolę, niezależnie od sposobu, w jaki widok otrzymuje identyfikator obiektu. –

8

Aktualizacja dla Django 1.6 i dodatkowo wersja

# forms.py 
# ... 
class MyForm(forms.ModelForm): 

    class Meta: 
    model = MyModel 

# views.py 

def my_view(request, id): 
    instance = MyModel.objects.get(id=id) 
    form = MyForm(request.POST or None, instance=instance) 
    if form.is_valid(): 
      form.save() 
      return redirect('next_view') 
return direct_to_template(request, 'my_template.html', {'form': form}) 
+0

Jeśli widok zawiera plik lub obraz, jaki byłby widok opisu? – Leonardo

+0

Leonardo MyForm (request.POST lub None, request.FILES lub None, ...) –

+0

Jak przekazać argument z szablonu do funkcji my_view? Mam na myśli z {% url 'my_view'%} –

Powiązane problemy