Search code examples
djangodjango-modelsdjango-select-related

Need help using data from a Select_related() queryset


I'm working on a parts database, where every part number can also be an assembly, meaning it is composed of any number of other parts (and the loop can go on, subparts being made of even more parts, etc). So there are two database tables, one for part information, and the other for relationship information- a part number linked to its "subpart" number. Keep in mind that "assemblies", "parts", and "subparts" are all ultimately just "parts (kind of confusing, but it allows for a more DRY and versatile database).

I'm currently using the select_related call to follow the ForeignKeys used in my model. However, because my query may return more than just a single result (if multiple subparts), I can't use the "get" lookup and I'm using "filter" instead. So- I can't follow the examples shown in the documentation which are all based off a get query.

The select_related query seems to be grabbing what I intend for it to (based on the raw SQL queries shown by DjangoDebugToolbar). But, I don't know how to call it! What is the correct syntax or method for displaying values from the related tables? How can I loop over every instance within the returned queryset? The snippet below from the template should most effectively show what I'm trying to obtain as a result. Thanks.

#----------------
#MODEL SNIPPET
#----------------
class Part(models.Model):
    ISC_CHOICES = ( #intentionaly removed for this question 
    )
    part_no = models.CharField(max_length=15, primary_key=True)
    description = models.CharField(max_length=40, blank=True, null=True)
    isc = models.CharField(max_length=2, choices=ISC_CHOICES)
    rev = models.CharField(max_length=2, blank=True, null=True)

#this table relates subparts to the part model above- basically is a manual many-to-many field
class PartAssembly(models.Model):
    id = models.AutoField(primary_key=True)
    part_no = models.ForeignKey(Part, related_name="partno_set")
    subpart = models.ForeignKey(Part, related_name="subpart_set")
    qty = models.IntegerField(max_length=3)
    item_no = models.IntegerField(max_length=3)


#----------------
#VIEW SNIPPET
#----------------
def assembly_details(request, assembly_no): #assembly_no passed through URL
    context_instance=RequestContext(request)
    subpart_list = PartAssembly.objects.filter(part_no=assembly_no).select_related()
    return render_to_response('assembly_details.html', locals(), context_instance,)


#-------------------
# TEMPLATE SNIPPET
#-------------------
{% for partassembly in subpart_list %} 
# obviously, this  loop doesnt return anything for my part.foo variables below
# it does work for the partassembly.bar
        <tr>
            <td>{{ partassembly.item_no }}</td> #EDIT: comments are correct
            <td>{{ partassembly.subpart }}</td> #partassembly.subpart.part_no
            <td>{{ part.description }}</td> #partassembly.subpart.description
            <td>{{ part.rev }}</td>     #partassembly.subpart.rev   
            <td>{{ partassembly.qty }}</td>
            <td>{{ part.isc }}</td>         #partassembly.subpart.isc
        </tr>

Thanks for any help


Solution

  • I'm not sure where your trouble is exactly. Remember that select_related() does not in any way change the object access for related instances - all it does is pre-cache them. So you refer to partassembly.part_no.rev and so on, exactly as if you were not using select_related.