I wasn’t sure how to word this exactly. But I have a model that lists a bunch of stores (complete with name, address, phone, etc). I also want to list and store links attributed to the store, so like say a Yelp Review, Yellowpages link, etc.
Instead of constantly adding columns, I was kind of thinking having a different model that lists a bunch of types of “link sources” like Yelp, Yellowpages, etc. and then another that actually cross references them so a row will have like store id 3, has a link at link type yelp.
Any ideas how I would accomplish this so an admin can dynamically add another link type, like say Google Places, and then will be able to add a link to a store’s Google Places page to a store?
You basically have two options based on what kind of relationship you want to model with your ‘references’:
models.ForeignKey(if the model with the ForeignKey should have a link to exactly one model of a specific type in another django model) ormodels.ManyToManyField(if its a many to many relationship).This is a bit abstract, so I’ll give a concrete example of each option.
Say you have a Store model, where each store contains at most one review, but the same review can point to multiple stores. Then it may make sense to have a model like this:
As written above you could have Stores A, B, C, where store A and store B both link to review 1, and store C links to review 2. This seems a bit silly; a review of a store should only point to one store (and you should be allowed to have stores with no reviews or multiple reviews; but shouldn’t be able to have a review that doesn’t point to a store). So it makes much more sense to construct it like:
This way each review points to exactly one store; but a store doesn’t necessarily have a review. If you have a variable
store_objwith an instance of a specific store you can iterate through all the reviews with by the querysetstore_obj.review_set.all().Now lets say you have two models say
StoreandHotelthat are fundamentally different, but want only one review class to link to both. This is wherecontenttypes/GenericRelationcome in. Its a bit more complicated than simple ForeignKey (as you have to keep track of the type and object_id and then construct the GenericForeignKey), but could be implemented as follows. (Obviously this would only make sense if you really need different fields/methods in Hotel and Store, unlike this example.)Actually upon re-reading your answer I think what you want is just something like:
So each review is linked to one store, you can give a list of choices to be stored in the database ‘yelp’, ‘ypag’ represented by longer text strings, as well as the hyperlink.
You could also create separate classes for each type of review if they are fundamentally different; e.g., if you were doing movie reviews a rotten tomatoes review would store fundamentally different information than a metacritic review. But it doesn’t matter as long as each model has a FK pointing back to Store.
If you need the admin to edit the list of review-types, the way to do it is as a foreignkey. Something like:
As you knew you’d have some initial ReviewType objects, I used get_or_create to create them based on id (on id, so if an admin edits the name “Yellow Pages” to say “Yellowpages” a new object is never created).
To make it so you can add a review from the admin page of the Store, you need to use inline models:
https://docs.djangoproject.com/en/1.3/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin
So on your admin.py page, do something like