views:

292

answers:

3

I expect this is an easy question. For some reason, I don't have a solution yet.

I have an object set from django reversion: version_list. Each object in the set has a user id attached to it. How do I grab the user names that correspond to the user ID's?

To try to be clearer, if each object in version_list has a name, date, and user id, how can I join the version_list set with the user table to figure out what user id goes with which name? This is done in the view, or the template?

A: 

Does the version object has a user property (i.e., ForeignKey) or is it just an integer field? If it's a user foreign key, you should be able to say:

{% for v in version_list %}
{{ v.user.get_full_name }}
{% endfor %}

Otherwise you're going to need to add a function/ property to your version objects that looks up the related user, like

from django.contrib.auth.models import User

def related_user(self):
    try:
        return User.objects.get(pk=self.user_id)
    except User.DoesNotExist:
        return None

And then in your template:

{% for v in version_list %}
{{ v.related_user.get_full_name }}
{% endfor %}
Tom
I don't believe the object has a user property. Just an integer field for user_id. I would like to avoid adding any function to the version model. I figure there ought to be a way to do a lookup without tying it together like that. For instance, when you use the django admin, you can see user and time of an edit made through that interface. The reversion app hooks into the admin so that edits made outside of that interface are also listed - with both times and user names. Is there a way to do something like populate a user_list set for which user_ids equal the ids from the version_list set?
Ed
A: 

Unless this is for some sort of legacy compatibility, you should really change your schema to use a ForeignKey(User). The data should be the same for this column, so if you already have a lot of stuff you don't want to lose in your database just update the model field to

user = models.ForeignKey(User)

and you won't even have to alter the table if the field is already called user_id.

As for getting the user's name, this is always done at the template level but it depends on whether you want a full name (Casey Stark) or a username (caseywstark).

Use {{ user }} to display the username and {{ user.get_full_name }} to display a full name. The second method calls the get_full_name function of the User object inside your template. Just keep in mind that you must set user.first_name and user.last_name in order for this to not return an empty string.

{% for version in version_list %}
    {{ version.user }} wrote version {{ version }}
{% endfor %}
Casey Stark
This could work. But I don't want to alter the model from its current state
Ed
If you *really* can't alter the model, then the template tag is probably the templatetag is the way to go. But I highly recommend dealing with this now as all other Django code is based on using ForeignKey(User). Django-flag, for instance, assumes that you have a ForiegnKey(User) in any object you want to flag. Using the easy fix now will just create more headaches later.
Casey Stark
A: 

I think you're looking for a simple template tag.

from django import template
from django.contrib.auth.models import User

register = template.Library()

@register.simple_tag
def get_username_from_userid(user_id):
    try:
        return User.objects.get(id=user_id).username
    except User.DoesNotExist:
        return 'Unknown'

Which you would use like:

{% for version in version_list %}
  {% get_username_from_userid version.user_id %}
{% endfor %}
Justin Lilly