2015-05-22 2 views
3

Я новичок в python, начал с python 3 и django1.8. Можем ли мы передать словарь в качестве параметра с несколькими значениями в нем, но меньше аргументов в определении функции.словарь python как параметр с несколькими значениями в словаре

def save_myobj(request): 
    ''' 
    ''' 
    reqobj = dict(zip(request.POST.keys(), request.POST.values())) 
    my_dict = prepare_profile_dict(**reqobj) 
    obj = Model.objects.get(pk=1) 
    obj.__dict__.update(my_dict) 
    obj.save() 
    return HttpResponse("true") 

Вот мой запрос объекта:

reqobj = { 
      u'csrfmiddlewaretoken': u'xzlrzJkpKb0aAIvdJ7Z7aX05uhHjnwjX', 
      u'email': u'', 
      u'first_name': u'abc', 
      u'last_name': u'def', 
      u'revenue': u'' 
      } 

и здесь prepare_profile_dict

def prepare_profile_dict(first_name, last_name, email): 
    ''' ''' 
    return { 
      "revenue" : get_revenue(), 
      "first_name":first_name, 
      "last_name":last_name, 
      "email":email 
      }; 

Но получить ошибки,

TypeError at /profile/save/ 
prepare_profile_dict() got an unexpected keyword argument 'revenue' 

Я не думаю, что есть что-нибудь делать с Mod эл.

class Model(models.Model): 
    ''' 
    ''' 
    first_name = models.TextField("first_name", blank=True, null=True, db_index=True) 
    last_name = models.TextField("last_name", blank=True, null=True, db_index=True) 
    email = models.TextField("email", blank=True, null=True, db_index=True) 
    revenue = models.IntegerField() 
+0

Как выглядит ваша модель? – Evert

+1

Я предполагаю, что 'prepare_my_dict' должен быть' prepare_profile_dict'? – Evert

+1

Вы можете, если вы измените функцию 'prepare_profile_dict', чтобы взять параметр' ** kwargs' в конце. –

ответ

4

Ваш prepare_profile_dict не принимает revenue аргумент (как указано в сообщении об ошибке); только first_name, last_name и email. Однако расширение dict при вызове функции содержит ключевое слово revenue. Либо удалите его из reqobj:

del reqobj['revenue'] 

или добавить **kwargs аргумент в конце prepare_profile_dict, чтобы поймать любые дополнительные аргументы ключевых слов (которые будут игнорироваться внутри функции).

def prepare_profile_dict(first_name, last_name, email, **kwargs): 
    ... 

(Очевидно, что то же самое для csrfmiddlewaretoken.)


Кроме того, вы можете использовать querysets update метода:

def save_myobj(request): 
    reqobj = dict(zip(request.POST.keys(), request.POST.values())) 
    my_dict = prepare_profile_dict(**reqobj) 
    # ensure my_dict only contains relevant keys 
    Model.objects.get(pk=1).update(**my_dict) 
    # No .save method needed 
    return HttpResponse("true") 
+0

спасибо. Я не могу голосовать, кроме +1 для '.update (** reqobj)'. Я этого не знал. – Laxmikant

+0

@ Evert- В моем случае в модели будет только один объект. Но эта строка не работает 'obj = Model.objects.all() [: 1] .get(). Update (my_dict)' Получение ошибки 'AttributeError at/profile/save/ Объект 'Model' не имеет атрибута 'update'' – Laxmikant

+0

Вам не нужен' Model.objects.all() [: 1] .get() '; это перебор. – Evert

2

Здравомыслящее решение с использованием ModelForm:

# forms.py 
from django import forms 
from .models import Profile 
from .somewhere import get_revenue 

class ProfileForm(forms.ModelForm): 
    class Meta: 
     model = Profile 
     fields = "__all__" 

    def clean_revenue(self): 
     return get_revenue() 

# views.py 
from .forms import ProfileForm 
from .models import Profile 

def save_myobj(request): 
    if request.method !== "POST": 
     return HttpResponseNotAllowed(["POST"]) 

    profile = Profile.objects.get(pk=1) 
    form = ProfileForm(request.POST, instance=profile) 
    if form.is_valid(): 
     form.save()   
     return HttpResponse("true") 
    # returning form.errors might be better 
    # but anyway: 
    return HttpResponse("false") 
+0

@brunosdesthuilliers - Спасибо! 'HttpResponseNotAllowed' для меня является новым. Я проверю его документ для более подробной информации. – Laxmikant

Смежные вопросы