Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AttributeError: 'str' object has no attribute 'fields' Using Django non rel on GAE

I'm doing an app with Django non rel on Google App Engine, and im using Bootstrap...to use Bootstrap on Django Forms i installed django_forms_bootstrap (https://github.com/pinax/django-forms-bootstrap)

The thing is...when i deploy on GAE and trying to create a new user (registration) i get the Server Error (500), but the new user is created...the log of GAE show this:

> Exception in request: Traceback (most recent call last):   File
> "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/core/handlers/base.py",
> line 113, in get_response
>     response = callback(request, *callback_args, **callback_kwargs)   File
> "/base/data/home/apps/s~softsystemanager/1.378394621720949564/myapp/modulos/presentacion/views.py",
> line 32, in signup_view
>     return render_to_response('presentacion/login.html', context_instance=RequestContext(request))   File
> "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/shortcuts/__init__.py",
> line 29, in render_to_response
>     return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/loader.py",
> line 177, in render_to_string
>     return t.render(context_instance)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 140, in render
>     return self._render(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 134, in _render
>     return self.nodelist.render(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 830, in render
>     bit = self.render_node(node, context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 844, in render_node
>     return node.render(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/loader_tags.py",
> line 124, in render
>     return compiled_parent._render(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 134, in _render
>     return self.nodelist.render(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 830, in render
>     bit = self.render_node(node, context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 844, in render_node
>     return node.render(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/loader_tags.py",
> line 63, in render
>     result = block.nodelist.render(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 830, in render
>     bit = self.render_node(node, context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 844, in render_node
>     return node.render(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 881, in render
>     output = self.filter_expression.resolve(context)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django/template/base.py",
> line 606, in resolve
>     new_obj = func(obj, *arg_vals)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django_forms_bootstrap/templatetags/bootstrap_tags.py",
> line 20, in as_bootstrap
>     form = _preprocess_fields(form)   File "/base/data/home/apps/s~softsystemanager/1.378394621720949564/django_forms_bootstrap/templatetags/bootstrap_tags.py",
> **line 10, in _preprocess_fields
>     for field in form.fields: AttributeError: 'str' object has no attribute 'fields'**

Then i go to the file bootstrap_tags.py and i see no error

> def _preprocess_fields(form):
>     for field in form.fields:
>         name = form.fields[field].widget.__class__.__name__.lower()
>         if not name.startswith("radio") and not name.startswith("checkbox"):
>             form.fields[field].widget.attrs["class"] = " form-control"
>     return form
> 
> 
> @register.filter def as_bootstrap(form):
>     template = get_template("bootstrap/form.html")
>     form = _preprocess_fields(form)
> 
>     c = Context({
>         "form": form,
>     })
>     return template.render(c)

In the HTML file of my app i got this

<div class="col-md-4 ">
            <form action="." method="POST">
                {%csrf_token%}
                {{ form|as_bootstrap}}
                <button type="submit" class="btn btn-default">Sign UP</button>
            </form>     
        </div>
    </div>

and i don't know if this is useful but here is the form

class RegisterForm(forms.Form):
    username = forms.CharField(label="Nombre de Usuario",widget=forms.TextInput())
    name = forms.CharField(label="Nombre",widget=forms.TextInput())
    last_name = forms.CharField(label="Apellido",widget=forms.TextInput())
    email = forms.EmailField(label="Correo Electronico", widget=forms.TextInput())
    password_one = forms.CharField(label="Password", widget=forms.PasswordInput(render_value=False))
    password_two = forms.CharField(label="Confirmar Password", widget=forms.PasswordInput(render_value=False))

In fact, the error is with this particular form, because i have another one, the login form, and it works perfectly and im using the same procedure to use the django_forms_bootstrap

The source code of my singup_view is:

def signup_view(request):
    form = RegisterForm()
    if request.method == "POST":
        form = RegisterForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            name = form.cleaned_data['name']
            last_name = form.cleaned_data['last_name']
            email = form.cleaned_data['email']
            password_one = form.cleaned_data['password_one']
            password_two = form.cleaned_data['password_two']
            newUser = User.objects.create_user(username=username, first_name=name, last_name=last_name, email=email, password=password_one)
            newUser.save()
            return render_to_response('presentacion/login.html', context_instance=RequestContext(request))
        else:
            ctx = {'form':form}
            return render_to_response('presentacion/sign_up.html',ctx, context_instance=RequestContext(request))
    ctx = {'form':form}
    return render_to_response('presentacion/sign_up.html',ctx, context_instance=RequestContext(request))

Please Help!!!

like image 496
user3117112 Avatar asked Sep 02 '14 04:09

user3117112


1 Answers

In your login.html template, you have {{ form|as_bootstrap }}, but in your code for signing up, you are rendering the template for login, but you are not passing in the form value:

return render_to_response('presentacion/login.html',
                          context_instance=RequestContext(request))

There is no context here.

You need to fix this by redirecting the user to the login view, instead of rendering the login template from your sign up view.

In addition, you should use the render shortcut which will automatically send RequestContext.

Your are also not checking for duplicate users.

To fix these issues in your code:

from django.shortcuts import render, redirect

def signup_view(request):
    form = RegisterForm(request.POST or None)
    ctx = {'form': form}
    if request.method == "POST":
        if form.is_valid():
            username = form.cleaned_data['username']
            name = form.cleaned_data['name']
            last_name = form.cleaned_data['last_name']
            email = form.cleaned_data['email']
            password_one = form.cleaned_data['password_one']
            password_two = form.cleaned_data['password_two']
            if not User.objects.filter(email=email).exists():
                 newUser = User.objects.create_user(username=username,
                                                    first_name=name,
                                                    last_name=last_name,
                                                    email=email,
                                                    password=password_one)
                 newUser.save()
            else:
                 # Do something, because a user
                 # with this email already exists
                 pass
            return redirect('login')

    return render(request, 'presentacion/sign_up.html', ctx)
like image 100
Burhan Khalid Avatar answered Sep 19 '22 19:09

Burhan Khalid