2009-06-02 16 views
11

Piszę aplikację Django, która wykonuje różne funkcje, w tym wstawianie lub aktualizowanie nowych rekordów do bazy danych za pośrednictwem adresu URL.Jak zaktualizować członków obiektu za pomocą dyktatury?

Tak więc niektóre aplikacje wewnętrzne wysyłają żądanie na przykład do /import/?a=1&b=2&c=3. W widoku chcę utworzyć nowy obiekt, foo = Foo() i ustawić element foo na dane w słowniku request.GET.

Oto, co robię teraz:

  1. wniosek przesłany do /import/?a=1&b=2&c=3
  2. View tworzy nowy obiekt: foo = Foo()
  3. Obiekt jest aktualizowane danymi.

Oto co mam do tej pory:

foo.a = request['a'] 
foo.b = request['b'] 
foo.c = request['c'] 

Oczywiście jest to żmudne i podatne na błędy. Dane w adresie URL mają dokładnie taką samą nazwę jak elementy obiektu, więc jest to proste mapowanie 1 do 1.

Idealnie, chciałbym zrobić w stanie zrobić coś takiego:

foo = Foo() 
foo.update(request.GET) 

lub coś w tym rodzaju.

Dzięki!

+1

Rozwiązanie przedstawione przez mrówki robi to, co chcesz, ale jak ty obsługę walidacji i typ konwersji? Albo nie budzą obaw (trudno mi w to uwierzyć). –

+0

Nie martwią się. Jest to wykorzystywane całkowicie w domu, gdzie dane są wstawiane do jednej bazy danych (z walidacją), a następnie (tutaj) wstawiane do innej. –

Odpowiedz

19

Można użyć funkcji setattr dynamicznie ustawić atrybuty:

for key,value in request.GET.items(): 
    setattr(foo, key, value) 
+0

Dzięki. Musiałem mieć pierdnięcie mózgu, ponieważ przeglądałem wbudowane funkcje dokumentacji. –

+0

Możesz zamienić 'a_dict' na' request' i 'obj' z' foo' na kod Nicka. –

+0

Zaktualizowałem, jeśli to dobrze z Ants. Dzięki jeszcze raz! –

1

pan prawie dostał.

foo = Foo(**request.GET) 

powinien załatwić sprawę.

+0

Występuje błąd: __init __() słowa kluczowe muszą być ciągami znaków –

+1

Słowa kluczowe mogą występować jako kod Unicode powodujący ten błąd. coś do znalezienia ... Ten kod pracował dla mnie z trzema różnymi sposobami pisania __init __() – JCotton

+2

To nie rozwiązuje przypadku użycia aktualizacji istniejącego modelu z dyktowaniem nowych wartości. –

1

Jeśli używasz tego do utworzenia obiektu modelu, który następnie zostanie utrwalony, zdecydowanie polecam używanie ModelForm. W ten sposób zrobiłbyś to, co opisałeś, w kanoniczny sposób dla Django, z dodatkiem sprawdzania poprawności.

Aby rozwinąć - nie chciałem użyć go do wyjścia formularza, tylko dane wejściowe formularza. W następujący sposób:

class Foo(models.Model): 
     a = models.CharField(max_length=255), 
     b = models.PositiveIntegerField() 

class FooForm(forms.ModelForm): 
     class Meta: 
      model = Foo 

def insert_foo(request): 
     form = FooForm(request.GET) 
     if not form.is_valid(): 
      # Handle error conditions here 
      pass 
     else: 
      form.save() 

     return HttpResponse('Your response') 

Następnie, zakładając, że związany/Import /, a dostać się do/Import/a = test & b = 1 będzie wstawić nowy Foo z = "test" i B = "1? ".

+0

Nie chcę formularza ani interakcji użytkownika. Skrypt, który wysyła dane, jest uruchamiany w trybie cron z dnia na dzień, aby zaktualizować bazę danych używaną przez Django do innych celów. –

3

Jeśli request.GET jest słownikiem i class Foo nie używa __slots__, to powinien również pracować:

# foo is a Foo instance 
foo.__dict__.update(request.GET) 
+0

Nie działa już w Django 1.3+ –

+0

Działa to w Django 1.6 z prawdziwym obiektem dict. Nie próbowałem request.GET lub .POST. – James

Powiązane problemy