How does ForeignKey work in this Django example? - django-models

I am having trouble understanding how to use ForeignKey and what exactly it does. Does it link two tables? Or does it link specific columns between each table? Here is a very basic example:
class Seller(models.Model):
name = models.CharField()
email = models.CharField()
zipcode = models.CharField()
class ItemsForSale(models.Model):
item = models.CharField()
description = models.CharField()
zipcode = models.ForeignKey(Seller)
What I'm trying to do is when someone fills out a form to sell an item, I want the zipcode for that item to be automatically set as the sellers zipcode (so the end user won't even have to fill out a zipcode in the form).
Why is it ForeignKey(Seller) instead of ForeignKey(Seller.zipcode)? I guess I don't understand am I linking the entire 'Seller' table? Or just the zipcode column?
Since I don't understand how ForeignKey works, I don't know how to write a view method that sets the zipcode for ItemsForSale. so I really think the key to helping me understand all this would be to see a proper view method that sets the ItemForSale's zipcode to the Sellers zipcode.

In Django a ForeignKey is a relationship between Objects.
In a database a ForeignKey is a field (column) in a table that links to a row of another table.
Visit the django docs and wikipedia for more information about ForeignKeys.
Now to your Django example:
Every single Item (ItemsForSale) has a Seller. (Note: Model names should always be singular.)
So we add a ForeignKey in your ItemsForSale-model that relates to the item's seller:
class ItemsForSale(models.Model):
...
seller = models.ForeignKey(Seller)
Now you can access the item's seller (and of course all of his attributes (including his zipcode) this way:
ItemsForSale.get(item='Foo').seller.zipcode

Related

How to real time filter foreign key dropdown, based on previous foreign key dropdown selection in the model form?

I have 2 models, Jobs and Çompany. Both are taken as a foreign key to my current model Tracker. In the tracker CreateView form I am selecting the Company from the drropdown(Company model), also the Job Position(Job model).
The Job model also has a company field, which says for which company the job position is open.
Now, what I want is, in my tracker form, as soon as I select a company from the dropdown, I want only the Job openings of that company to be listed in the Job foreign key dropdown.
Let's say there are 3 job openings for Google, Engineer, Support and Developer. Currently my job position dropdown is displaying all the positons in the job model list. I want to filter them based on the company I select.
And the company also I'm chosing from the dropdown beside only, in the same form.
Is there a way, I can filter the dropdown real time?
Like having a dynamic foreign key dropdown which depends on my Company value chosen(dropdown again)?
class Tracker(models.Model):
company_applied = models.ForeignKey(Company, on_delete=models.CASCADE)
position_applied = models.ForeignKey(Jobb, on_delete=models.CASCADE)
class Jobb(models.Model):
position = models.CharField(max_length=100)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
def __str__(self):
return self.position_applied
class Company(models.Model):
company_name = models.CharField(max_length=100)
...
def __str__(self):
return self.company_name
How to achieve it? I searched a lot, I'm not able to find the exact words to search to get the solution.
Also I'm new to Django..

An item with multiple categories in DB

I have a contacts table and a contact_category table. I am trying to reflect in table that one contact can belong to several categories.
Is there any recommended design pattern for implementing this? What comes to my mind is just creating a string in an additional field for every contact and concat the categories this contact belongs to.
For ex.:
"cat1,cat3" would mean that a contact belongs to cat1 and cat3
But, isn't there any proper way of designing this?
Generally speaking, a comma-delimited text field with multiple values is a bad idea in database design, in my rarely-humble opinion.
I'd recommend something like this (I code in SQL Server, so that's what my syntax will look like):
Contact
ID -- primary key
-- other contact fields
Category
ID -- primary key
-- other category fields
Contact_Category
Contact_ID -- foreign key to Contact
Category_ID -- foreign key to Category
The above allows you to associate a contact to multiple categories and a category to multiple contacts. Let me know if you have any questions.

How to implement on to many relation ? datastore google app engine

my application have business entity, and each business belong to one or more category !
How should implement the relation in my database ?
I have two options,
first option :
(to store all the categories that belong to specific business, at the business entity.)
class business(ndb.Model):
name = ndb.StringProperty()
categories = ndb.KeyProperty(kind=category,repeated=True)
class category(ndb.Model)
name = ndb.StringProperty()
the second option :
(to store all the business that belong to a specific category at the category entity)
class business(ndb.Model):
name = ndb.StringProperty()
class category(ndb.Model)
name = ndb.StringProperty()
businesses = ndb.KeyProperty(kind=business,repeated=True)
which option should I implement ?
Another problem:
every business could have one or more image:
should I store the images in list inside the business entity :
class business(ndb.Model):
name = ndb.StringProperty()
imagesUrl = ndb.StringProperty(repeated = True)
or create new entity for each image :
class image(ndb.Model):
businessKey = ndb.KeyProperty(repeated = True)
imageUrl = ndb.StringProperty()
I know that the entity size is limited to one mega! yes ?
Decisions like this one usually depend on your usage patterns. In you case, however, it looks like option 1 is the logical choice, because there are many more business entities than category entities.
For example, if you need to know which categories a business belongs to when you retrieve a single business entity, you will have to run an extra query if you choose option 2. With option 1, this extra query is unnecessary.
Another consideration is the frequency of updates. If you go with option 2, you will have to update your category entity every time you add a new business entity (thus, two entities have to be updated, which impacts performance and costs). With option 1 you only need to update one entity.

Which is the best way to relate some tables?

I want to make an application where there will be different users and each user will have a set of friends which will be put in categories. There will be some default categories, but the user will be able to add his own. I was wondering which will be the best way to do this.
My idea is to have 3 tables - user, friends and categories.
The user table to have fields (one to many) for friends and categories (but I don't know if the user table will need any information about the friends and the categories at all).
The friends table to have a field for categories (one to many) and a field for the user (many to one).
The category table to have fields for user (many to many?) and friends (many to many?).
I'm not sure about the relations, too. I'm using PHP with MySQL and Symfony2 and Doctrine2. Please help!
EDIT
Maybe I haven't described exactly what I need. When you open the app, you see a login form. If you don't have an account, you should register - the registration creates a new user. This user isn't connected with other users (I'm still new to programming and I want something a little easier so it's something like phonebook). Each user has a list of friends and a firend is a row in a table with fields such as name, addres, phone, email, photo, birthday and so on, but they are added by the current user. The friends are not users. Every user is in fact an account with password and username and when you log in there is just a list of friends. So each user creates categories for himself and he has nothing to do with other users and their categories. The category will have only id and name.
So the idea is that you create an account, then create some categories and add friends to them just to have an organiser when you friends are born or where they live, or which is their phone number, but you create them and add the information about them, they are to users themselves. It's not like a social network. Just a notebook where each user can write info about his friends.
First of all, you need to understand the role of intersection tables: if user A labels user B as a friend (i.e. there is a many-to-many relation from user to itself), and you create a new table to represent that relation (the friends table), any additional information about this "friendship" should be linked to that table. So, if a user categorizes his friends in some way, the category applies to friends, not to user. There's no need for a relation between category and user for this specific purpose.
Update: since friends are not users, the friends table will not be an intersection table (and thus have only one reference back to user, denoting the "owner"), but the rest of the answer still applies.
I'm assuming each category will be a row in the category table. Additional information about the category might be added, but it should be limited to that. For instance, if you want to know which user created a category, you could add a foreign key to user labeled for instance "owner" or "created_by". That might be useful if categories created by one user are not to be seen by others.
Finally, you can relate friends with category. If User A can put user B in at most one category, then a foreign key from friends to category should suffice (i.e. a one to many relation). Otherwise, you might need another many-to-many relation, so an additional intersection table should be created (for instance friend_category).
You could avoid this extra table by employing denormalization, having multiple rows in friends where both users are the same (and in the same order) but the category is different (see also this example). Whether this is advantageous or not is beyond the scope of this answer, but IMHO using an extra table is better for now (it might seem more complicated, but it will be easier to maintain in the long run). (Update: if friends is not an intersection table, denormalizing like this is not really an option, so stick with the friend_category table)
In the end, your layout would look like this:
user friends friend_category category
---- ------- --------------- --------
(user fields) <-- user (owner) <-- friend (category fields)
(friend fields) category --> user (owner) --+
^ |
| |
+--------------------------------------------------------------------+
I can suggest the following table set for this (this scheme applies to the phonebook or social network tasks as well):
Table "Users" that stores all the information about users:
UserId
Name
Phone
Address
... (any other fields)
Table "Categories" that stores information about relationship categories:
CategoryId
Name
Table "Relationships" that stores information about relationships between users:
FirstUserId -> Link to Users table
SecondUserId -> Link to Users table
CategoryId -> Link to Categories table
So, any user is able to add new categories, and then reference them when adding new relationship to another person.
If you need to select all user's friends, you will have to:
select fr.* from Relationships r join Users fr on r.SecondUserId = fr.UserId where r.FirstUserId = <Current user id>

Cakephp related tables show id's instead of values

i think i have all 'baked' all my relationships correctly but my 'related' table shows id's instead of values.
my db has 3 tables. candidates, qualificationlookups, qualifications.
qualificationlookups, links candidates to qualifications using the id of the candidate and the id of the qualification.
in my view view, for 'candidates', i have a 'related qualificationlookups' table. (generated by baking a candidate hasmany qualificationlookups and a qualificationlookups belongsto candidate relationship)
in my edit view, for 'qualificationlookups', i can correctly set up the candidates and qualifications fields as dropdowns so i know 'qualificationlookups's relationships are fine.
So how do i ask cakephp to list the name of the qualification (from 'qualifications' table) in the 'related qualificationlookups' table on a candidate's page?
i must be missing something...
could someone please point me in the right direction?
Thanks, Vauneen
Whenever CakePHP automagically fetches lists from your tables, it uses the id key for the value and the $displayField for the text.
If your table has a name or title field, CakePHP automatically displays it as the display field. So, either rename the field that you want as your display field (say, candidate_name to just name) or set the $displayField variable in your model:
class Candidate extends AppModel {
var $displayField = 'candidate_name';
}
HTH.
If there is no other data being stored in the qualificationlookups table, change the relationship to candidates -> HABTM -> qualifications.
To do this, you first need to drop the qualificationlookups table. Create a new table called candidates_qualifications with two indexes, candidate_id and qualification_id.
In your Candidate and Qualification models, define a HABTM Relationship. You do not need to make a new CandidatesQualification Model, cake will do it on the fly.

Resources