Merge lp:~dylanmccall/harvest/opportunityqueryset into lp:harvest

Proposed by Dylan McCall
Status: Merged
Merged at revision: 304
Proposed branch: lp:~dylanmccall/harvest/opportunityqueryset
Merge into: lp:harvest
Diff against target: 167 lines (+34/-22)
4 files modified
harvest/opportunities/feeds.py (+2/-3)
harvest/opportunities/models.py (+23/-2)
harvest/opportunities/views.py (+5/-5)
harvest/opportunities/wrappers.py (+4/-12)
To merge this branch: bzr merge lp:~dylanmccall/harvest/opportunityqueryset
Reviewer Review Type Date Requested Status
Daniel Holbach Approve
Review via email: mp+59703@code.launchpad.net

Description of the change

I had implemented a rather horrible way of selecting only valid opportunities; a function in opportunities.wrappers which had to be called with a queryset as a parameter. This branch does something a little tidier, with a custom OpportunityManager and OpportunityQuerySet implementing an only_valid method. This way we can grab valid opportunities without writing gigantically long lines of code :)

It also fixes an issue that popped up recently where opportunities with no visible opportunities were still listed in the filter view (because they weren't being removed properly).

To post a comment you must log in.
Revision history for this message
Daniel Holbach (dholbach) wrote :

This looks great! Thanks a lot for your work on this!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'harvest/opportunities/feeds.py'
2--- harvest/opportunities/feeds.py 2011-05-02 02:39:20 +0000
3+++ harvest/opportunities/feeds.py 2011-05-02 21:04:54 +0000
4@@ -5,7 +5,6 @@
5 from django.utils.translation import string_concat
6
7 import models
8-from wrappers import get_valid_opportunities
9
10 class _OpportunitiesFeed(Feed):
11 def item_title(self, opp):
12@@ -35,7 +34,7 @@
13 return reverse('filter')
14
15 def items(self):
16- valid_opps = get_valid_opportunities(models.Opportunity.objects.order_by('-last_updated'))[:25]
17+ valid_opps = models.Opportunity.objects.only_valid().order_by('-last_updated')[:25]
18 if (valid_opps):
19 return valid_opps
20 else:
21@@ -52,7 +51,7 @@
22 return reverse('single_package', args=[pkg.name])
23
24 def items(self, pkg):
25- return get_valid_opportunities(pkg.opportunity_set.order_by('-last_updated'))
26+ return pkg.opportunity_set.only_valid().order_by('-last_updated')
27
28 def item_title(self, opp):
29 return opp.description
30
31=== modified file 'harvest/opportunities/models.py'
32--- harvest/opportunities/models.py 2010-12-08 08:15:50 +0000
33+++ harvest/opportunities/models.py 2011-05-02 21:04:54 +0000
34@@ -2,6 +2,7 @@
35
36 from django.contrib.auth.models import User
37 from django.db import models
38+from django.db.models import F
39 from django.utils.translation import ugettext_lazy as _
40
41 PACKAGE_GREEN_THRESHOLD = 5
42@@ -55,6 +56,23 @@
43 return self.name
44
45
46+class OpportunityQuerySet(models.query.QuerySet):
47+ def only_valid(self):
48+ return self.filter(valid=True,
49+ opportunitylist__active=True,
50+ last_updated=F('opportunitylist__last_updated'))
51+
52+class OpportunityManager(models.Manager):
53+ def get_query_set(self):
54+ return OpportunityQuerySet(self.model)
55+
56+ def __getattr__(self, attr, *args):
57+ #pass getattr through to our custom queryset
58+ try:
59+ return getattr(self.__class__, attr, *args)
60+ except AttributeError:
61+ return getattr(self.get_query_set(), attr, *args)
62+
63 class Opportunity(models.Model):
64 description = models.TextField(_("Description"), max_length=350)
65 url = models.URLField(_("URL"), max_length=350, verify_exists=False)
66@@ -75,6 +93,9 @@
67 def __unicode__(self):
68 return self.description
69
70+ objects = OpportunityManager()
71+ objects.use_for_related_fields = True
72+
73 @property
74 def summary(self):
75 summary_list = []
76@@ -110,7 +131,7 @@
77
78 def log_action(who, action=None, opportunity=None):
79 log_entry = ActionLogEntry(timestamp=datetime.datetime.now(),
80- who=who, action=action,
81- opportunity=opportunity)
82+ who=who, action=action,
83+ opportunity=opportunity)
84 log_entry.save()
85
86
87=== modified file 'harvest/opportunities/views.py'
88--- harvest/opportunities/views.py 2011-02-22 04:13:14 +0000
89+++ harvest/opportunities/views.py 2011-05-02 21:04:54 +0000
90@@ -22,7 +22,7 @@
91 sourcepackages_list = filters_pkg.process_queryset(sourcepackages_list)
92
93 #opportunities_list is filtered right away to only check opportunities belonging to selected packages
94- opportunities_list = models.Opportunity.objects.all()
95+ opportunities_list = models.Opportunity.objects.only_valid()
96 opportunities_list = opportunities_list.filter(sourcepackage__in=sourcepackages_list)
97 opportunities_list = filters_opp.process_queryset(opportunities_list)
98
99@@ -60,7 +60,7 @@
100 def single_package(request, package_name):
101 package = get_object_or_404(models.SourcePackage, name=package_name)
102
103- opportunities_list = package.opportunity_set
104+ opportunities_list = package.opportunity_set.only_valid()
105 package_wrapper = PackageWrapper(request, package, visible_opportunities = opportunities_list)
106
107 context = {
108@@ -74,7 +74,7 @@
109
110 def json_package_summary(request, package_name):
111 package = get_object_or_404(models.SourcePackage, name=package_name)
112- opportunities_list = package.opportunity_set
113+ opportunities_list = package.opportunity_set.only_valid()
114 data = {}
115 for opportunity in opportunities_list:
116 if not data.has_key(opportunity.opportunitylist.name):
117@@ -170,8 +170,8 @@
118
119 package = get_object_or_404(models.SourcePackage, id=package_id)
120
121- opportunities_list = package.opportunity_set
122- opportunities_list = filters.find('opp').process_queryset(opportunities_list).all()
123+ opportunities_list = package.opportunity_set.only_valid()
124+ opportunities_list = filters.find('opp').process_queryset(opportunities_list)
125
126 package_wrapper = PackageWrapper(request, package, visible_opportunities = opportunities_list, expanded = True)
127
128
129=== modified file 'harvest/opportunities/wrappers.py'
130--- harvest/opportunities/wrappers.py 2011-02-22 03:25:18 +0000
131+++ harvest/opportunities/wrappers.py 2011-05-02 21:04:54 +0000
132@@ -1,13 +1,5 @@
133-from django.db.models import F
134 from harvest.common.url_tools import update_url_with_parameters
135
136-# Returns all valid opportunities in the given QuerySet
137-def get_valid_opportunities(opportunities_list):
138- if opportunities_list:
139- return opportunities_list.filter(valid=True,
140- opportunitylist__active=True,
141- last_updated=F('opportunitylist__last_updated'))
142-
143 class PackageWrapper(object):
144 """
145 Describes a visible source package, for specific use in a
146@@ -40,7 +32,7 @@
147 #order_by should really happen in the template, but the template
148 #language's dictsort is unstable pending a fix to Django bug
149 #11008: <http://code.djangoproject.com/ticket/11008>
150- opps = get_valid_opportunities(self.visible_opportunities)
151+ opps = self.visible_opportunities
152 return opps.order_by('-since', 'opportunitylist', 'experience')
153
154 def get_hidden_opportunities(self):
155@@ -48,9 +40,9 @@
156 Returns opportunities that belong to the given package but have
157 been hidden from view
158 """
159- visible_opps = self.get_visible_opportunities()
160- all_opportunities = self.package.opportunity_set.exclude(id__in=visible_opps)
161- return get_valid_opportunities(all_opportunities)
162+ visible_opps = self.visible_opportunities
163+ all_opportunities = self.package.opportunity_set.only_valid().exclude(id__in=visible_opps)
164+ return all_opportunities
165
166 class PackageListWrapper(object):
167 """

Subscribers

People subscribed via source and target branches

to all changes: