Cry for Help: Need an Expert to Assist Newbie on Accessing Foreign Key Objects

Clearly I’m a beginner here, but you gotta know I’m determined. I know the view code below is screwy, but what I’m trying to do is query a foreign key and bring in the related object. I’m having trouble–blurry eyed by now from looking at this for most of the afternoon–seeing how to bring in the related collector object. And I know it’s easy! I’m building a directory of artist files collections across Canada, Mexico, and U.S. Each collection uses a foreign key out to a related collector, which can be an institution or person.

I’ll be thrilled to learn from someone who is willing to lead me out of this

https://github.com/samdale67/artist-files-directory

Thank you,
Samuel Duncan | Head of the Research Library
Amon Carter Museum of American Art
3501 Camp Bowie Blvd., Fort Worth, TX 76107
samd@cartermuseum.org | 817.989.5042

from django.shortcuts import get_object_or_404, render
from .models import Collection
from collectors_app.models import Collector


def collection_detail(request, collection_id):
    collection = get_object_or_404(Collection, pk=collection_id)
    collector_query = Collection.objects.select_related('collector').filter(id=collection_id).get()
    collector_institution_type = Collector.inst_type.all()
    collector_person_type = Collector.person_type.all()
    service = collection.service.all()
    cat_system = collection.cat_system.all()
    spec_format = collection.spec_format.all()
    subject_name = collection.subject_name.all()
    subject_topic = collection.subject_topic.all()
    subject_city = collection.subject_city.all()
    template = 'collections_app/collection_detail.html'
    context = {'collector': collector,
               'collector_institution_type': collector_institution_type,
               'collector_person_type': collector_person_type,
               'collection': collection,
               'service': service,
               'cat_system': cat_system,
               'spec_format': spec_format,
               'subject_name': subject_name,
               'subject_topic': subject_topic,
               'subject_city': subject_city}
    return render(request, template, context)

As a beginner, one key thought to remember is not to try to do too much when you’re not sure of the direction you’re heading.

I’d trim a lot of this down to the smallest sample that will demonstrate parts of the key functionality.

Having said that, it would be very helpful if you were a lot more specific as to the problems you’re having. What is it that you’re looking for assistance with? What error messages are you receiving? Getting a traceback on the console? Templates not rendering as desired?

Also, you’ve made a major boo-boo by putting your settings.py file in a public repository with private credentials still in there - especially if any of this is pulled from other resources.

Ken

I realize that boo-boo, but as this is just in development, I’ll change settings.py by the time this goes into production. Basically I need guidance on how to access the related collector object so I can use its attributes in my template.

And, Ken, thanks kind stranger. I know it’s a lot to chew as a beginner, but I’ve come so far. Somehow this foreign key stuff is not intuitive to me.

I’m happy to help - but I’d need to ask you to be a lot more specific with the current issue you’re facing.

What is happening / not happening as you expect? (Error messages? Unexpected data in the templates? “White page”?) The more information you can provide, the better my chances of giving you an answer that will be of any value.

Ken

One thing we link to in the Django “Getting Help” FAQ is the Stack Overflow guide on asking good questions:

Sometimes just writing your question well will help you answer it yourself :wink:

Let me try to elaborate. My app has two models, one representing a collection of artist files material (think scrapbook clippings), and the other representing the collector (either a person or institution) that own the material. I’m writing a query which finds a collection based on its PK then finds the related collector record based on a foreign key in the collection model. The part I’m fuzzy about, and the part that the documentation doesn’t cover abundantly, is how to bring in the related object and all its attributes into the view, so that I can then access them in the template called collection_detail, which brings all the fields from collection and collector together. You may be able to see from github that each model have a number of many-to-many-keys. I’m tripping up on the “collector_query,” which pulls objects from the Collection model, not the Collector model.

Think I may be getting closer, but I don’t know how to handle the filter, in other words how do I match the two based on collection_id, which is what is passed to the function?

def collection_detail(request, collection_id):
    qs = Collection.objects.select_related('collector').filter(collection_id=collection_id).get()
    collection = qs[0]
    collector = collection.collector
    collector_institution_type = collector.inst_type.all()
    collector_person_type = collector.person_type.all()
    service = collection.service.all()
    cat_system = collection.cat_system.all()
    spec_format = collection.spec_format.all()
    subject_name = collection.subject_name.all()
    subject_topic = collection.subject_topic.all()
    subject_city = collection.subject_city.all()
    template = 'collections_app/collection_detail.html'
    context = {'collector': collector,
               'collector_institution_type': collector_institution_type,
               'collector_person_type': collector_person_type,
               'collection': collection,
               'service': service,
               'cat_system': cat_system,
               'spec_format': spec_format,
               'subject_name': subject_name,
               'subject_topic': subject_topic,
               'subject_city': subject_city}
    return render(request, template, context)

Think I nailed it …

def collection_detail(request, collection_id):
    collection = Collection.objects.get(pk=collection_id)
    collector = collection.collector
    collector_institution_type = collector.inst_type.all()
    collector_person_type = collector.person_type.all()
    service = collection.service.all()
    cat_system = collection.cat_system.all()
    spec_format = collection.spec_format.all()
    subject_name = collection.subject_name.all()
    subject_topic = collection.subject_topic.all()
    subject_city = collection.subject_city.all()
    template = 'collections_app/collection_detail.html'
    context = {'collector': collector,
               'collector_institution_type': collector_institution_type,
               'collector_person_type': collector_person_type,
               'collection': collection,
               'service': service,
               'cat_system': cat_system,
               'spec_format': spec_format,
               'subject_name': subject_name,
               'subject_topic': subject_topic,
               'subject_city': subject_city}
    return render(request, template, context)

I really think, if you’re in my shoes as a beginner, you see that learning this stuff is truly like learning another language, an argot. I just don’t quite have all syntax rules down, but I’m inching closer.

What I think you’re looking for is in the Making queries page of the documentation under Following relationships backward.

When people are struggling with a particular concept, I like to refer them back to the official tutorial when it applies - and this is one of those cases. If you haven’t worked your way through it, I suggest you do so.
If you have, you might want to go back and review the work you had done on the polls app and find the parallels between your models and the models used in that app.

Ken