sharataka
sharataka

Reputation: 5132

How to retrieve an object with a parameter?

I am trying to select a certain user based on a user_id but am having some trouble. I'm getting an error saying "invalid literal for int() with base 10":

The relevant parts of the code are below:

urls.py

url(r'^user/(?P<user_id>[-\w]+)/$', 'view_reviews_user'),

models.py

class UserProfile(models.Model):
    user = models.ForeignKey(User, primary_key=True)
    quote = models.CharField('About', max_length =  200, null=True, blank=True)

views.py

def view_reviews_user(request, user_id):
    reviews = Reviewbackup.objects.filter(user=user_id)
    reviews = reviews.order_by("-created_on")
    userprofile = UserProfile.objects.get(user=user_id)
    return render_to_response('reserve/templates/user.html', {'reviews':reviews, 'user_id': user_id, 'userprofile': userprofile},
        context_instance=RequestContext(request))

I believe the error is in the "pk=user_id" but am not sure how to fix it. I tried "user_id=user_id" but that does't seem to work either. I am trying to access "quote" in the template eventually. Any advice?

Upvotes: 0

Views: 104

Answers (2)

miki725
miki725

Reputation: 27861

You have to remember what is going on before the view gets called.

Django does regex to match the url with some pattern. Now usually regex expressions will have groups in them to be able to parse out some ids from there. Django will take those ids and pass them to the view. However since it just uses regex, the values of those groups will be strings even if your groups are something like (?P<user_id>\d+).

So within your view, user_id is a string, whereas foreign key in your model is an integer, hence Django wants an integer to do the query. All you have to do is cast the value to an integer and you should be fine (refer below on how to make sure the user_id does not contain other non-integer characters in it):

def view_reviews_user(request, user_id):
    userprofile = UserProfile.objects.get(pk=int(user_id))

Even though that will work, many things can go wrong here.

What about if the user does not type an integer? That is easily fixed in the regex in urlconfig by using \d+ which will only match the expression if there are only integers. So then you can be sure that int(user_id) will not raise an issue.

url(r'^user/(?P<user_id>\d+)/$', 'view_reviews_user'),

What about if the user is not found? user might provide user_id but that user id might not exist. You should handle that. The easiest way is to use django shortcut get_object_or_404 like:

get_object_or_404(UserProfile, pk=user_id)

PS: It's not recommended to use a foreign key to a User within UserProfile. Since there is one-to-one relationship between users and their profiles, you should user OneToOneField instead of a ForeignKey.

EDIT

If you want to be able to query users by their username instead of their id, you can do that like:

def view_reviews_user(request, username):
    userprofile = get_object_or_404(UserProfile, user__username=username)

Upvotes: 2

Chris Pratt
Chris Pratt

Reputation: 239290

Your user_id is a string. Django ids are ints, if you want to use a string like 'sharat' you should add a SlugField to your model, and then query the slug:

def view_reviews_user(request, slug):
    userprofile = UserProfile.objects.get(slug=slug)

Upvotes: 1

Related Questions