We love designing and developing websites, but what really drives us is solving problems and cultivating strong relationships with our clients
Doing things with Django models - aka - Django models tutorial
By : shabda
Django abstracts most of the actions you would be doing with the Database. What it doesn't abstracts, and doesn't try to abstract is the Database modelling part. This is a quick tutorial describing to how model your data in Django models.py, and how to access and modify them.
Consider a hypothetical HR department, which wants you to build an application to track and manage their processes. They have employees who work for a department, contractors who work for multiple department. Let's see how you you would do that in Django.
from django.db import models
class Employee(models.Model):
name = models.CharField(max_length = 100)
department = models.ForeignKey("Department")
class Department(models.Model):
name = models.CharField(max_length = 100)
class EmployeeHistory(models.Model):
employee = models.OneToOneField(Employee)
date_joined = models.DateField()
marital_status = models.BooleanField()
class Contactor(models.Model):
name = models.CharField(max_length = 100)
departments = models.ManyToManyField(Department)
Let's see the type of relationship we created here.
An Employee has a Many-to-one relationship with Department, (i.e. One department will have many
Employee, but one employee will have a single departments.)
So Employee has a field department = models.ForeignKey("Department"). See that the ForeignKey field
was added on the class which has in many. In database, this creates a FK from in Employee table which refernces
Departments.
A Contractor has many-to-many relationships with Department, so it has a ManyToMany field. This field can be created
on either classes. At a database level this creates a new table which has a FK to both the tables.
A Employee has one-to-one relationship with EmployeeHistory. The thing to note here is that whatever we could do with
OneToOneField, we can do by including the fields in the Other Class directly. However when there are fields which are only rarely
needed with a given model, it is useful to separate them via a one-to-one field. The one to one field can be on either class.
Accessing objects.
Getting a specific employee.
Employee.objects.get(pk = someval)
Employee.objects.get(name= someval)
Given an department get all employees.
department.employee_set.all()
The department gets an attribute name <FKClass>_set.
Given an employee, get all colleagues.
employee.department.employee_set.objects.all()
To get siblings, get parents, and get all children.
Given an department, get number of employees.
department.employee_set.all().count()
Ok so the HR department bosses are happy with what they see, and ask you to track this data, who is the manager of each employee, who is the HOD of each department and when did each employee took leave.
from django.db import models
class Employee(models.Model):
name = models.CharField(max_length = 100)
manager = models.ForeignKey("self", blank = True, null = True)
department = models.ForeignKey("Department")
class Department(models.Model):
hod = models.ForeignKey("Employee")
name = models.CharField(max_length = 100)
class EmployeeHistory(models.Model):
employee = models.OneToOneField(Employee)
date_joined = models.DateField()
marital_status = models.BooleanField()
class Contactors(models.Model):
name = models.CharField(max_length = 100)
departments = models.ManyToManyField(Department)
class EmployeeLeave(models.Model):
leave_taken = models.DateField()
employee = models.ForeignKey(Employee)
So we now have new fields hod = models.OneToOneField("Employee") in department and
manager = models.ForeignKey("self", blank = True, null = True) and a new model EmployeeLeave. Let su see
the new realtions,
As one Department will have one Employee as hod, and Employee can head at max one Department, we have a one to one relationship
As many Employee will report to another Employee, so we have a FK on Employee, referencing self.
As Employee will take many EmployeeLeave, EmployeeLeave has a FK to Epployee
Let us see some queries.
Get all leaves taken by an employee this year
import datetime
today = datetime.date.today()
start_of_year = datetime.datetime(today.year, 1, 1)
leaves_taken = employee.employeeleave_set.filter(leave_taken__gt=start_of_year, leave_taken__lt = today)
Get a list of all HODs.
#As there are going to be as many Employees as departments
departments = Department.objects.all()
employees = [department.hod for department in departments]
Get a list of all departments a contractor works for.
contractor.department_set.all()
Get a list of all contractor who work for a department.
department.contractor_set.all()
Note that each side of a many to many relationship get a Manager.
List of all managers in a given department.
Todo#(Can't think of any one query way to do this. If you know, let me know :) )
List of all leaves taken in a given department.
EmployeeLeave.objects.filter(employee__department = department)
None that we used double underscores __ to do a filtering on a field across Entities.
List of all employees which joined a given department this year.
Employee.objects.filter(department = department, employment_history__date_joined__gte=start_of_year, )
Note that we used a double underscore __ twice, first to go across entities, and then to define the type of filter(__gte).
Also we specified two filter conditions, so they were ANDed together.
List all employees which either report too a given employee, or joined before him.
Employee.objects.filter(Q(manager = employee)|Q(employee_history__date_joined__lt = employee.employee_history.date_joined))
Note the new construct Q, they are used to specify complex boolean operations. Here we used the | (or operator) to specify or condition.
Do you subscribe to our rss feed? The new feed has full text feed and many other goodness. So make sure you are subscribed to the new feed with extra fortified vitamins. Subscribe now.
Comments
@Kenneth, well its a large company with hierarchical management, so managers have managers. (WIth pointy hairs).
List of all managers in a given department.
dept = Department.objects.all()[0]
Employee.objects.filter(department=dept, manager__isnull=True)
@valKirian
Same as above,
you are assuming that managers have no managers. :)
CAn you make a screenshot of the tables and the relations?
It helps to understand the tutorial
Thanks
“List of all managers in a given department.â€
managers = Employee.objects.filter(manager__isnull=False).filter(department__name = "mydepartment")
“List of all managers in a given department.â€
Haven't tested it, but something like this:
managers=Employee.objects.filter(employee__isnull=False,department=dept)
manager is an employee to employee relationship so the reverse relationship (based on the django docs) will be available as employee_set as an attribute and in query terms to traverse it you'd use employee.
It'd be made clearer by defining the manager field on Employee as:
manager = models.ForeignKey("self", blank = True, null = True, related_name="manages")
So you could then have:
managers=Employee.objects.filter(manages__isnull=False,department=dept)
Reactions
Doing things with Django models – aka – Django models tutorial: Django abstracts most of the actions you would be … http://bit.ly/8irAKE
This comment was originally posted on Twitter
http://uswaretech.com/blog/2010/01/django-models-tutorial/ Doing things with Django models aka Django models tutorial.
This comment was originally posted on Twitter
Doing things with Django models – aka – Django models tutorial http://goo.gl/fb/ZM9B #django
This comment was originally posted on Twitter
Doing things with Django models – aka – Django models tutorial — The Usware Blog – Django Web Development: http://bit.ly/8B6lgF
This comment was originally posted on Twitter
Doing things with Django models – aka – Django models tutorial — The Usware Blog – Django Web Development: http://bit.ly/5LiCOz
This comment was originally posted on Twitter
- Deploying Django apps on Heroku
- Dynamically attaching SITE_ID to Django Caching
- Screencast: How to deploy Django on Heroku
- How to use pep8.py to write better Django code
- Screencast: Django Tutorial Part 1
- How and why to use pyflakes to write better Python
- Getting started with South for Django DB migrations
- A brief overview of Vagrant
- Writing jQuery plugins using Coffeescript
- Behind the Scenes: Request to Response
- rails
- django
- linkroundup
- django opinion
- opinion
- business
- API
- appengine
- python
- satire
- startup
- Uncategorized
- marketing
- personal
- rambling
- search
- interviews
- seo-interviews
- 5startupideas
- ideas
- seo
- tips
- forms
- paypal
- utilities
- datetime
- web2.0
- Amazon
- algorithms
- presentations
- products
- pinax
- satchmo
- ecommerce
- microsoft
- yahoo
- book
- tutorial
- models
- aggreagtion
- meta
- India
- apps
- about
- CSS
- Design
- wordpress
- test slug
- vim
- urls
- reviews
- javascript
- xmpp
- emacs
- Typography
- Grid Theory
- Color Theory
- iphone
- android
- titanium
- mobile applications
- CSS3
- Browser Compatibility
- mobile
- jobs
- lamson
- django setup
- files
- upload
- jsTree
- hierarchical view
- web page
- Treeview
- coffeescript
- request
- response
- South
- django south
- django migration
- --fake
- screencasts
- django caching
- SITE_ID prefix
- April 2012
- February 2012
- January 2012
- December 2011
- October 2011
- September 2011
- July 2011
- June 2011
- April 2011
- February 2011
- January 2011
- December 2010
- November 2010
- October 2010
- September 2010
- June 2010
- April 2010
- March 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- April 2009
- March 2009
- February 2009
- November 2008
- October 2008
- June 2008
- May 2008
- April 2008
"List of all managers in a given department."
Assuming managers don't have managers themselves:
department.employee_set.objects.filter(manager=None)