On Sat, Jun 30, 2012 at 5:26 PM, Nick Apostolakis <nicka...@oncrete.gr> 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 code. 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 models.py 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 consistency: for example, the friendship request method: def send_friend_request(self, target): try: f = Friendship.objects.get(personA=self, personB=target) return f in (Friendship.REQUESTED, Friendship.ACCEPTED) except Friendship.DoesNotExist: Friendship.objects.create( personA=self, personB=target, state=Friendship.REQUESTED) 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 changes. 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. -- Javier -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.