cannot concatenate 'str' and 'WSGIRequest' objects - django

I keep getting this error when I try to load my templates:
TypeError: cannot concatenate 'str' and 'WSGIRequest' objects
Here is a link to the paste: https://gist.github.com/3b7039baf13d91a67de2
You will notice that one of the lines from the traceback points to my views.py and the last line in the method below. Could this last line be the problem and if so how can I go about fixing it. Thanks in advance
def all(request):
"""This returns all the photos in the database
"""
return render_to_response(request, 'photos/all.html', {'photos':
Photo.objects.all().order_by('-date_added')})

render_to_response doesn't accept request as its first argument.
render, from Django 1.3, however does. Perhaps that the method you intended to use?

Related

TypeError: 'NoneType' object is not iterable Django Filter Values_List

I've been trying to figure out an error that I can't get past this afternoon. I am using a Class Based View(DetailView).
Here is my code...
def get_context_data(self, **kwargs):
book = list(Author.objects.filter(author_id).values_list('publisher'))
When I try to execute my code...
I get....
TypeError: 'NoneType' object is not iterable
I know at times the values_list('publisher') for an Author may sometimes be blank. How can I get this filter mechanism to bypass the book if the publisher is in fact empty?
I tried to do something like...
def get_context_data(self, **kwargs):
book = list(Author.objects.filter(author_id).values_list(None, 'publisher'))
But it didn't seem to help. I also played with the idea of making this reference conditional but that seems unnecessary. Is there some way to get this code bypassed if in fact the lookup is NONE?
I'm using PostgreSQL.
Thanks in advance for any thoughts.

Why does adding Regexp arguments in Django urls.py completely break HTTP response mechanism?

I have changed the way URLS are handled in my Django app.
Previously I was posting my model IDs as named variables in the URLs. But now, I am instead embedding my model IDs in the URL itself which looks more elegant to me. However, doing so is seemingly giving me a problem TypeError: <myObject: Object #4> is not JSON serializable
My Django Application used to be structured like this:
Old urls.py:
url(r'^doSomethingStep1/?$', views.doSomethingStep1View, name='doSomethingStep1'),
url(r'^doSomethingStep2/?$', views.doSomethingStep2View, name='doSomethingStep2'),
Old views.py doSomethingStep1() function:
#login_required
def doSomethingStep1View(request):
myObjectObj = Prediction.objects.get(pk=int(request.GET["p"]))
...
return HttpResponseRedirect(reverse("doSomethingStep2"))
This used to work fine. But now I have changed it to the code shown below:
New urls.py:
url(r'^doSomethingStep1/(?P<myObjectID>\d+)/(?P<myObjectSlug>[a-z0-9\-_]+)/?$', views.doSomethingStep1View, name='doSomethingStep1'),
url(r'^doSomethingStep2/(?P<myObjectID>\d+)/(?P<myObjectSlug>[a-z0-9\-_]+)/?$', views.doSomethingStep2View, name='doSomethingStep2')
New views.py doSomethingStep1() function:
#login_required
def doSomethingStep1View(request, myObjectID, myObjectSlug=None):
...
return HttpResponseRedirect(reverse(
"doSomethingStep2",
kwargs={
'myObjectID': myObjectObj.id,
'myObjectSlug': myObjectObj.slug,
}
)
)
Running this view now (by visiting /doSomethingStep1/4/myobject-4-slug) yields the following error in the Browser:
TypeError at /doSomethingStep1/4/myobject-4-slug <MyObject: myObject 4 Slug> is not JSON serializable
It's really confounding. Why is this happening and how to fix it? I have printed out the value of reverse and there is no problem with it. I have no clue why and where it is trying to serialize MyObject4. As far as I know, it shouldn't be trying to serialize this object.
Are you using Django 1.6? The default session serializer was switched to JSON, which can cause problems if you put something in the session that is not serializable. You can switch back to the old pickle serializer using the SESSION_SERIALIZER setting. See the 1.6 release notes for details:
https://docs.djangoproject.com/en/dev/releases/1.6/#default-session-serialization-switched-to-json
You didn't include all of your view code, but I'm betting you are putting a MyObject instance in the user's session, which wouldn't get serialized and throw the error until the redirect happens.

Django - How to pass a string value from the urlconf to feeds.py class

I'm struggling with something that I am sure has a very simple method, but I am not getting it right. I am trying to pass a value from the urlconf to the feeds.py file. What I am trying to do is generate specific feeds for comments on a page.
I have been reading the example in the documentation:
http://docs.djangoproject.com/en/dev/ref/contrib/syndication/
of how to use the get_object() method, but I cannot seem to pass the right values.
Here is what I have been trying. In the url.py file:
('^post/(?P<sl>.*)/comment_feed/$', CommentFeed()),
And in the feeds.py file:
class CommentFeed(Feed):
def get_object(self, request, sl):
return get_object_or_404(Post, ????)
And I keep getting a ValueError saying:
invalid literal for int() with base 10: 'Test-1'
What is the right way to pass the object to the feeds CommnetFeed class?
Looks like you were testing it with post/Test-1/comment_feed/ - were you?
Django expects an integer as the post id. Give it a number as in post/12/comment_feed/ and use pk=sl as done in the example given in the linked page.
return get_object_or_404(Post, pk=sl)

redirect to another page instead of recieving Django standarf 404 error

i have something like this in my views.py
instance = get_object_or_404(register,pk=request.user.id)
Now if there is no related object against this user i receive i standard django 404 eror
saying no matches found.
what i want here is instead of receiving this 404 error redirect it to another page say "something.html". but i dont know how. i am using method = "POST"
is there any way to redirect it to other page instead of receiving a 404 error
using a try/except block you can redirect if the object is not found
try:
instance = register.get(pk=request.user.id)
except register.DoesNotExist:
return HttpResponseRedirect('url that renders something.html')
FYI, definition of django get_object_or_404 function looks like this
def get_object_or_404(klass, *args, **kwargs):
"""
Uses get() to return an object, or raises a Http404 exception if the object
does not exist.
klass may be a Model, Manager, or QuerySet object. All other passed
arguments and keyword arguments are used in the get() query.
Note: Like with get(), an MultipleObjectsReturned will be raised if more than one
object is found.
"""
queryset = _get_queryset(klass)
try:
return queryset.get(*args, **kwargs)
except queryset.model.DoesNotExist:
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
from the docs, If you raise Http404 at any point in a view function, Django will catch it and return the standard error page for your application, along with an HTTP error code 404.
look at customizing error views if you want to render a custom 404.html based on the context variables
Depending on what the Big Picture is, you might want to look at django.contrib.flatpages and see what they are doing. Basically they are dealing with the 404 in middleware and then looking at the path to decided if there is something they can return. I have used variations on this on a couple of sites.

adding errors to Django form errors.__all__

How do I add errors to the top of a form after I cleaned the data? I have an object that needs to make a REST call to an external app (google maps) as a pre-save condition, and this can fail, which means I need my users to correct the data in the form. So I clean the data and then try to save and add to the form errors if the save doesn't work:
if request.method == "POST":
#clean form data
try:
profile.save()
return HttpResponseRedirect(reverse("some_page", args=[some.args]))
except ValueError:
our_form.errors.__all__ = [u"error message goes here"]
return render_to_response(template_name, {"ourform": our_form,},
context_instance=RequestContext(request))
This failed to return the error text in my unit-tests (which were looking for it in {{form.non_field_errors}}), and then when I run it through the debugger, the errors had not been added to the forms error dict when they reach the render_to_response line, nor anywhere else in the our_form tree. Why didn't this work? How am I supposed to add errors to the top of a form after it's been cleaned?
You really want to do this during form validation and raise a ValidationError from there... but if you're set on doing it this way you'll want to access _errors to add new messages. Try something like this:
from django.forms.util import ErrorList
our_form._errors["field_name"] = ErrorList([u"error message goes here"])
Non field errors can be added using the constant NON_FIELD_ERRORS dictionary key (which is __all__ by default):
from django import forms
errors = my_form._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.util.ErrorList())
errors.append("My error here")
In Django 1.7 or higher, I would do:
form.add_error(field_name, "Some message")
The method add_error was added in 1.7. The form variable is the form I want to manipulate and field_name is the specific field name or None if I want an error that is not associated with a specific field.
In Django 1.6 I would do something like:
from django.forms.forms import NON_FIELD_ERRORS
errors = form._errors.setdefault(field_name, form.error_class())
errors.append("Some message")
In the code above form is the form I want to manipulate and field_name is the field name for which I want to add an error. field_name can be set to NON_FIELD_ERRORS to add an error not associated with a specific field. I use form.error_class() to generate the empty list of error messages. This is how Django 1.6 internally creates an empty list rather than instantiate ErrorList() directly.
You should raise the validationerror.
Why not put the verification within the form's clean method
class ProfileForm(forms.Form):
def clean(self):
try:
#Make a call to the API and verify it works well
except:
raise forms.ValidationError('Your address is not locatable by Google Maps')
that way, you just need the standard form.is_valid() in the view.
You're almost there with your original solution. Here is a base Form class I built which allows me to do the same thing, i.e. add non-field error messages to the form:
from django import forms
from django.forms.util import ErrorDict
from django.forms.forms import NON_FIELD_ERRORS
class MyBaseForm(forms.Form):
def add_form_error(self, message):
if not self._errors:
self._errors = ErrorDict()
if not NON_FIELD_ERRORS in self._errors:
self._errors[NON_FIELD_ERRORS] = self.error_class()
self._errors[NON_FIELD_ERRORS].append(message)
class MyForm(MyBaseForm):
....
All my forms extend this class and so I can simply call the add_form_error() method to add another error message.
I'm not sure how horrible of a hack this is (I've only really worked on two Django projects up until this point) but if you do something like follows you get a separate error message that is not associated with a specific field in the model:
form = NewPostForm()
if something_went_horribly_wrong():
form.errors[''] = "You broke it!"
If the validation pertains to the data layer, then you should indeed not use form validation. Since Django 1.2 though, there exists a similar concept for Django models and this is certainly what you shoud use. See the documentation for model validation.