Adam
Adam

Reputation: 558

Django Many to Many display values, not object

I'm working with Django 1.3, with the following 2 models:

class Person(models.Model):
    name = models.CharField(max_length=500)
    def __unicode__(self):
        return self.name

class Trial(models.Model):
    person = models.ManyToManyField(Person, blank=True)
    strId = str(id)
    def __unicode__(self):
        return self.strId

I am trying to display all the entries of "name" to a view, but I am currently returning only <django.db.models.fields.related.ReverseManyRelatedObjectsDescriptor object at 0x1019b45d0>

Which I can only see when I view the Page Source. Otherwise it just looks like a blank white screen.

The view is as follows:

def trial_entry(request, trial):
    currentTrial = Trial.objects.get(id = 1)
    personName = Trial.person
    return HttpResponse(personName)

I'm obviously returning the wrong thing here, but I've scoured for another way to do it and nothing I've found seems to work. This is about the only way I've found to return anything other than an error, so I figured that was the best thing to post.

Thanks very much

Upvotes: 2

Views: 3199

Answers (2)

Bartek
Bartek

Reputation: 15609

There are a few mistakes here. First, personName is not accessing any actual instance of Trial, rather you are just getting information about the person attribute within the Trial class.

So the first thing you need to do is change how you fetch persons.

currentTrial = Trial.objects.get(pk=1)
personName = currentTrial.person

Do you see what's different? I access currentTrial, which is the instance of the Trial class you are dealing with, within this view. Makes sense so far?

Now, currentTrial.person is actually a ManyToMany manager, which can be iterated through, since we can have many persons on a Trial. So we should adjust the variable names to make a bit more sense.

persons = currentTrial.person.all()

You could go one step further and simply send currentTrial to the template context, and then access that trials persons within your template like so:

{% for person in currentTrial.person.all %}
      {{ person }}
{% endfor %}

Hope that helps!

Upvotes: 5

adamnfish
adamnfish

Reputation: 11255

Firstly, Trial.person is a reference on the Trial model itself (the class), not an instance thereof. You should probably write it as currentTrial.person or trial.person depending on which trial you are interested in.

Secondly, you've used a many-to-many field for the person attirbute. This means that you can have multiple people associated with a trial - it would be more clearly named, 'people'.

If you really do mean people I'd suggest changing the name, but you actually get a queryset-like object back. You can do person.all() to get them all, or person.filter(something=value) to get a subset of the people associated with the trial.

If you really mean 'person' (a single preson associated with a trial) then you should use the ForeignKey field. This will associate a single person with the trial that can be accessed with currentTrial.person.

Good luck!

Upvotes: 2

Related Questions