2014-12-04 5 views
0

Я пытаюсь создать форму издания для выбранного пользователя моей CustomUser модели, но, к сожалению, это то, что я получаю при получении формы:Django виджеты: слишком много значений для распаковки

ValueError at /changeCustomUser/ too many values to unpack  

, который отслеживает меня оба файла шаблона и представлений - я буду отмечать места ошибок кода.

models.py

class CustomUserManager(UserManager): 
    def create_user(self, username, email=None, password=None, **extra_fields): 
     return UserManager.create_user(self, username, email=email, password=password, **extra_fields) 

    def create_superuser(self, username, email, password, **extra_fields): 
     return UserManager.create_superuser(self, username, email, password, **extra_fields) 

class CustomUser(AbstractUser): 
    role = models.CharField(max_length = 1, default = 'C') 

    objects = CustomUserManager() 

    class Meta(AbstractUser.Meta): 
     swappable = 'My_app.CustomUser' 

forms.py

class CustomUserChangeForm(UserChangeForm): 
    def __init__(self, choices_list, *args, **kwargs): 
     super(CustomUserChangeForm, self).__init__(*args, **kwargs) 
     if choices_list: 
      self.fields['role']=forms.ChoiceField(label='Function', choices=choices_list, widget=forms.Select, required = True) 
     del self.fields['password'] 
     del self.fields['username'] 

    class Meta(UserChangeForm.Meta): 
     model = CustomUser 
     fields = ('first_name', 'role') 

views.py

def changeCustomUser(request): 
    if request.method == 'POST': 
     customUserChangeForm = CustomUserChangeForm(request.POST, instance=request.user) 
     if customUserChangeForm.is_valid(): 
      customUserChangeForm.save() 
      return HttpResponseRedirect('/changeCustomUser/?customUser=saved') 
     else: 
      e1 = str(request.user) 
      if e1 == 'AnonymousUser': 
       context1={'welcome_id': 'Welcome Guest :)', 'form': 'Log in to change user details', 'error': ''} 
      else: 
"""ERROR TRACE""" 
       context1={'welcome_id': 'Welcome '+request.user.first_name + ' :)', 'form': customUserChangeForm,'error': 'Make data valid'} 
      return render_to_response('changeCustomUser.html', context1 ,context_instance=RequestContext(request)) 
    else: 
     e1 = str(request.user) 
     if e1 == 'AnonymousUser': 
      context1={'welcome_id': 'Welcome Guest', 'error': ''} 
     else: 
      if request.user.role == 'A': 
       customUserChangeForm = CustomUserChangeForm(initial = {'first_name': request.user.first_name, 'role': request.user.role}, 
       choices_list=[('A', 'B', 'C')] 
       ) 
      elif request.user.role == 'B': 
       customUserChangeForm = CustomUserChangeForm(initial = {'first_name': request.user.first_name, 'role': request.user.role}, 
       choices_list=[('B', 'C')] 
       ) 

      if request.GET.get('customUser', '') == 'saved': 
       context1={'welcome_id': 'Welcome '+request.user.first_name + ' :)', 'form': customUserChangeForm,'error': 'Details changed succesfully.'} 
      else: 
       context1={'welcome_id': 'Welcome '+request.user.first_name + ' :)', 'form': customUserChangeForm,'error': ''}  # SECOND ERROR TRACE 
     return render_to_response('changeCustomUser.html', context1 ,context_instance=RequestContext(request)) 

changeCustomUser.html

{# Other fields declared as follows, but without role conditions: #} 
{% if user.role == "A" or user.role == "B" %} 
    <tr> 
     <td>{{ form.role.label_tag }}</td> 
"""ERROR TRACE""" 
     <td>{{ form.role }}</td> 
    </tr> 
{% endif %} 

Как вы видите, я устанавливаю свои собственные привилегии в поле «role», и разные роли могут выполнять различные изменения. Возвращаясь к проблеме: Я пытался переключить request.user на некоторое время, передавая переменную из предыдущего обзора:

if request.GET.get('username_get', '') != '': 
    sub_user = Reader.objects.get(username=str(request.GET.get('username_get', ''))) 
else: 
    sub_user = request.user 

Это помогло мне по крайней мере отображать соответствующие данные пользователя, который я выбрал для изменения. К сожалению, этот пользовательский коммутатор длится только до тех пор, пока я не удалю POST из-за потери этого переданного аргумента, с тем же результатом ошибки, что и выше (слишком много значений для распаковки). Все, что мне удалось получить, - это редактирование зарегистрированного пользователя, а не пользователя, которого я выбрал для редактирования. Я попытался, конечно, выяснить, почему эти значения неверны, но веб-поиск только подтвердил, что им нужно оставаться в кортежевом формате, чтобы выборщик мог их обрабатывать. Любые идеи о том, как работать с выбранными пользователями с ролью «A»/«B»?

EDIT: My bad. Извините, потому что вы не слишком осторожны. Я говорю выше о кортежах и все же не предоставляю. Я получил их, как вы сказали:

choices_list=[('A','A'), ('B','B'), ('C', 'C')]  

Одиночный choice_list тоже не работает. Спасибо за очень полезные советы. Я немедленно улучшу свой код. Поскольку не существует никаких проблем с этой конкретной частью choices_list - полный отслеживающей ниже:

Environment: 
Request Method: POST 
Request URL: http://localhost:8000/changeCustomUser/ 
Django Version: 1.7.1 
Python Version: 2.7.6 
Installed Applications: 
('django.contrib.admin', 
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'My_app') 
Installed Middleware: 
('django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.common.CommonMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware', 
'django.middleware.clickjacking.XFrameOptionsMiddleware') 


Template error: 
In template /var/www/html/DjangoApps/My_app/templates/changeCustomUser.html, error at line 22 
    too many values to unpack 
    16 :  <td>{{ form.email.label_tag }}</td> 
    17 :  <td>{{ form.email }}</td> 
    18 : </tr> 
    19 : {% if user.role == "A" or user.role == "B" %} 
    20 : <tr> 
    21 :  <td>{{ form.role.label_tag }}</td> 
    22 :  <td> {{ form.role }} </td> 
    23 : </tr> 
    24 : {% endif %} 
    25 : <tr> 
    26 :  <td>{{ form.user_address.label_tag }}</td> 
    27 :  <td>{{ form.user_address }}</td> 
    28 : </tr> 
    29 : </table> 

Traceback: 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/core/handlers/base.py" in get_response 
    111.      response = wrapped_callback(request, *callback_args, **callback_kwargs) 
File "/var/www/html/DjangoApps/My_app/views.py" in changeCustomUser 
    88.    return render_to_response('changeCustomUser.html', context1 ,context_instance=RequestContext(request)) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/shortcuts.py" in render_to_response 
    23.  return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/loader.py" in render_to_string 
    178.   return t.render(context_instance) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/base.py" in render 
    148.    return self._render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/base.py" in _render 
    142.   return self.nodelist.render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/base.py" in render 
    844.     bit = self.render_node(node, context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/debug.py" in render_node 
    80.    return node.render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/loader_tags.py" in render 
    126.   return compiled_parent._render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/base.py" in _render 
    142.   return self.nodelist.render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/base.py" in render 
    844.     bit = self.render_node(node, context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/debug.py" in render_node 
    80.    return node.render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/loader_tags.py" in render 
    65.     result = block.nodelist.render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/base.py" in render 
    844.     bit = self.render_node(node, context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/debug.py" in render_node 
    80.    return node.render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/defaulttags.py" in render 
    312.     return nodelist.render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/base.py" in render 
    844.     bit = self.render_node(node, context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/debug.py" in render_node 
    80.    return node.render(context) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/template/debug.py" in render 
    93.    output = force_text(output) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/utils/encoding.py" in force_text 
    85.     s = six.text_type(s) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/forms/forms.py" in __str__ 
    508.   return self.as_widget() 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/forms/forms.py" in as_widget 
    560.   return force_text(widget.render(name, self.value(), attrs=attrs)) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/forms/widgets.py" in render 
    504.   options = self.render_options(choices, [value]) 
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.1-py2.7.egg/django/forms/widgets.py" in render_options 
    530.   for option_value, option_label in chain(self.choices, choices): 

Exception Type: ValueError at /changeCustomUser/ 
Exception Value: too many values to unpack  

PS Найдены три опечаток. Извините, но после целой ночи пытается заставить ее работать, я, возможно, не так сосредоточен, как должен.

ответ

0

Наконец-то я выиграл эту битву.

У меня не было прав на правильную работу в моей предыдущей конструкции.

Прежде всего - мне нужно было создать переменную "choice_list" в моем запросе POST.method "if" block. Здесь был клоу. Тогда и только тогда я мог бы создать свой customUserChangeForm, добавив еще один аргумент в конструкторе:

customUserChangeForm = CustomUserChangeForm(choices_list, request.POST, instance=sub_user) 

Последнее, что нужно сделать было пропускание имени пользователя пользователя, который был редактируемым это «если» из параметра GET и делает экземпляр sub_user для правильного имени пользователя и соответствия правильных значений choice_list.

Еще раз спасибо за помощь и советы.

PS Отслеживание ошибок не было таким конкретным, как оно должно и фактически указывало на неправильное место в файле views.py.

3

Пожалуйста, пост полный отслеживающий - но я подозреваю, что ваша проблема с этой линии:

choices_list=[('A', 'B', 'C')] 

список выбора должен быть последовательность (список или любой другой) из (value, label) пар.Заменить выше:

choices_list=[('A','A'), ('B','B'), ('C', 'C')] 

, а также это (который интерпретируется как единый список выбора со значением 'B' и этикеткой 'C'):

choices_list=[('B', 'C')] 

с:

choices_list=[('B', 'B'), ('C', 'C')] 

в качестве примечания:

Прочитать документ о Джанго AUTH и request.user: вы можете заменить этот

e1 = str(request.user) 
if e1 == 'AnonymousUser': 
    do_something() 

с

if request.user.is_anonymous(): 
    do_something() 

Научитесь использовать функции Строка форматирования в Python - вы можете заменить это:

'Welcome '+request.user.first_name + ' :)' 

с

'Welcome %s :)' % request.user.first_name 

или лучше: оставить презентацию шаблонный слой (где он принадлежит) , помните, что с настройками по умолчанию вы получите доступ к request.user в контексте вашего шаблона, не передавая его явно.

Узнайте, как правильно кодировать код, чтобы избежать повторений: у вас есть одинаковые блоки кода, скопированные в разные места, что в лучшем случае хрупкое (FWIW у вас уже есть одно место с опечаткой, посмотрите, можете ли вы его найти) ,

И наконец: научитесь использовать приложение сообщений Django (https://docs.djangoproject.com/en/1.6/ref/contrib/messages/) вместо того, чтобы изобретать квадратное колесо.

+0

Раздел редактирования добавлен с полной меткой. Проблема все еще существует. Любые другие идеи? – wisienka91

+0

Ошибка: «для параметра option_value, option_label в цепочке (self.choices, choice» ... У вас, очевидно, все еще есть неправильный список выбора. Если вы не знаете, где лучше всего добавить код отладки эта строка в исходном коде Django. –

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