未加星标

Django Models & Mixins for cleaner code

字体大小 | |
[开发(python) 所属分类 开发(python) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

I've been using Mixins lately to DRY -ly make certain behavior available to several different Django models. If you're not familiar with mixins, there's a great discussion over on StackOverflow .

Here's a simple example to illustrate what I've been doing. In building Work for Pie , we've got a UserProfile model that looks something like this:

class UserProfile(models.Model): user = models.OneToOneField(User) tagline = models.CharField(max_length=140) biography = models.TextField() avatar_url = models.URLField(max_length=256) # several other things, too...

But, we also have a number of other models that are associated with User objects, such as a Score :

class Score(models.Model): user = models.ForeignKey(User) score = models.IntegerField() # some other stuff

Now, there are a number of scenarios where you might want to display a User's Score , and that's not too difficult to do using the ORM. In fact, we've got a Manager method , latest , that lets us get the most recent Score associated with a User.

score = Score.objects.filter(user__username='bkmontgomery').latest()

However... that soon starts to feel redundant if you want to include a user's score elsewhere―in an other app or a somewhat unrelated model, for example. Image that we also have comments:

class Comment(models.Model): user = models.ForeignKey(User, help_text="The comment's author") content = models.TextField()

What if you always wanted to show a users score next to their comments? You might do something like this in a template ( assume comment is a Comment instance ):

<span class="score">{{ comment.user.score_set.latest }}<span>

Likewise, if you wanted to link back to the user's profile, you might do something like this:

<a href="{{ comment.user.userprofile.get_absolute_url }}">view profile<a>

This works, but it's fairly verbose.

Save some effort...

Here's where a Mixin can save you some work. First, let's assume that we want to be able to access a user's score on any model that also has a ForeignKey to User . You could build a ScoreMixin class like the following:

class ScoreMixin(object): """Mixin to another class to provide access to a User's ``Score``.""" @property def score(self): """Get the latest score for the User who saved this Job.""" if not hasattr(self, "_score"): self._score = self.user.score_set.latest() return self._score

Keep in mind: this code assumes any model that inherits from this class will have a user attribute.

We can now augment our Comment class as follows, which will give all Comment instances a score attribute:

class Comment(ScoreMixin, models.Model): user = models.ForeignKey(User, help_text="The comment's author") content = models.TextField()

Now, our template can be a bit more concise:

<span class="score">{{ comment.score }}<span>

I've found that simple cases like this, let me easily reuse some behavior for models that already have a common attribute or field.

本文开发(python)相关术语:python基础教程 python多线程 web开发工程师 软件开发工程师 软件开发流程

主题: DjangoRY
分页:12
转载请注明
本文标题:Django Models &amp; Mixins for cleaner code
本站链接:http://www.codesec.net/view/482417.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(python) | 评论(0) | 阅读(30)