Saturday, June 30, 2012

Re: advantages and disadvantages of Raw sql queries in django

On Sat, Jun 30, 2012 at 5:26 PM, Nick Apostolakis <> wrote:
> Interesting idea, I haven't used that yet, could you give an example of
> that?
> Would you use a method calling the ORM that would include something like
> self.objects.select_related().bla bla?

for example: when modelling the requested/accepted/rejected of a
'friendship' relation between 'person' records, you have to design the
exact DB representation, but later on you might want to modify that
representation. Ideally, such changes shouldn't impact _all_ your

specifically: my Person model has a ManyToManyField to 'self' called
'friends', where the intermediate table ('Friendship' model) has a
'state' field. These are implementation details, so i added some
methods to get the list of friends, list of unanswered requests sent,
received, and rejections sent and received:

def get_friends(self):
return self.friends.filter(as_B__state=Friendship.ACCEPTED)

def get_sent_requests_unanswered(self):
return self.friends.filter(as_B__state=Friendship.REQUESTED)

def get_rcvd_requests_unanswered(self):
return self.receivedRequests.filter(as_A__state=Friendship.REQUESTED)

def get_sent_requests_rejected(self):
return self.friends.filter(as_B__state=Friendship.REJECTED)

def get_rcvd_requests_rejected(self):
return self.receivedRequests.filter(as_A__state=Friendship.REJECTED)

as you can see, these queries are readable enough to be used anywhere;
but if later on i want to replace the single 'friends' link field with
several independent relationships, i don't have to search through all
my code, just the

similarly, there are methods to send a request and to accept or reject
it. Again, the code is simple enough that it could be used directly;
but encapsulating it with the Person model makes it easy to maintain

for example, the friendship request method:

def send_friend_request(self, target):
f = Friendship.objects.get(personA=self, personB=target)
return f in (Friendship.REQUESTED, Friendship.ACCEPTED)
except Friendship.DoesNotExist:
personA=self, personB=target,
return True

doesn't allow a second request if one is already pending or rejected.
if later on this policy is changed (maybe a rejector could change
mind, or an old request could expire, etc), i know where to do the

also, this lets the views be _really_ thin. since the interface
presented by the models is really close to the conceptual data objects
presented to the users. After that, adding for example a REST layer
isn't hard; since it only has to use the same high-level methods as
the HTML views. again, consistency is guaranteed by the common
underlying implementation.

in short: an application model is _not_ an OOP view of the database;
it's the implementation of the conceptual data objects as handled by
the application.


You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to
To unsubscribe from this group, send email to
For more options, visit this group at

No comments:

Post a Comment