US #50: Neighbor taking into account issues ordering
parent
9315e7b562
commit
778fce6257
|
@ -22,27 +22,32 @@ class NeighborsMixin:
|
|||
"""
|
||||
if queryset is None:
|
||||
queryset = type(self).objects.get_queryset()
|
||||
if not self._get_queryset_order_by(queryset):
|
||||
queryset = queryset.order_by(*self._get_order_by())
|
||||
queryset = queryset.order_by(*self._get_order_by(queryset))
|
||||
queryset = queryset.filter(~Q(id=self.id))
|
||||
|
||||
return self._get_previous_neighbor(queryset), self._get_next_neighbor(queryset)
|
||||
|
||||
def _get_queryset_order_by(self, queryset):
|
||||
return queryset.query.order_by or []
|
||||
return queryset.query.order_by
|
||||
|
||||
def _get_order_by(self):
|
||||
return self._meta.ordering
|
||||
def _get_order_by(self, queryset):
|
||||
return self._get_queryset_order_by(queryset) or self._meta.ordering
|
||||
|
||||
def _field(self, field):
|
||||
return getattr(self, field.lstrip("-"))
|
||||
def _get_order_field_value(self, field):
|
||||
field = field.lstrip("-")
|
||||
obj = self
|
||||
for attr in field.split("__"):
|
||||
value = getattr(obj, attr, None)
|
||||
if value is None:
|
||||
break
|
||||
obj = value
|
||||
|
||||
def _filter(self, field, inc, desc):
|
||||
return value
|
||||
|
||||
def _transform_order_field_into_lookup(self, field, operator, operator_if_order_desc):
|
||||
if field.startswith("-"):
|
||||
field = field[1:]
|
||||
operator = desc
|
||||
else:
|
||||
operator = inc
|
||||
operator = operator_if_order_desc
|
||||
return field, operator
|
||||
|
||||
def _format(self, value):
|
||||
|
@ -51,30 +56,39 @@ class NeighborsMixin:
|
|||
return value
|
||||
|
||||
def _or(self, conditions):
|
||||
condition = conditions[0]
|
||||
result = Q(**{key: self._format(condition[key]) for key in condition})
|
||||
for condition in conditions[1:]:
|
||||
result = result | Q(**{key: self._format(condition[key]) for key in condition})
|
||||
result = Q()
|
||||
for condition in conditions:
|
||||
result |= Q(**{key: self._format(condition[key]) for key in condition})
|
||||
return result
|
||||
|
||||
def _get_prev_neighbor_filters(self, queryset):
|
||||
conds = [{"{}__{}".format(*self._filter(field, "lt", "gt")): self._field(field)}
|
||||
for field in self._get_queryset_order_by(queryset)]
|
||||
return self._or(conds)
|
||||
def _get_neighbor_filters(self, queryset, operator, operator_if_order_desc):
|
||||
conds = []
|
||||
for field in self._get_queryset_order_by(queryset):
|
||||
value = self._get_order_field_value(field)
|
||||
if value is None:
|
||||
continue
|
||||
lookup_field, operator = self._transform_order_field_into_lookup(
|
||||
field, operator, operator_if_order_desc)
|
||||
lookup = "{}__{}".format(lookup_field, operator)
|
||||
conds.append({lookup: value})
|
||||
return conds
|
||||
|
||||
def _get_previous_neighbor(self, queryset):
|
||||
try:
|
||||
return queryset.filter(self._get_prev_neighbor_filters(queryset)).reverse()[0]
|
||||
except IndexError:
|
||||
return None
|
||||
def _get_prev_neighbor_filters(self, queryset):
|
||||
return self._get_neighbor_filters(queryset, "lte", "gte")
|
||||
|
||||
def _get_next_neighbor_filters(self, queryset):
|
||||
conds = [{"{}__{}".format(*self._filter(field, "gt", "lt")): self._field(field)}
|
||||
for field in self._get_queryset_order_by(queryset)]
|
||||
return self._or(conds)
|
||||
return self._get_neighbor_filters(queryset, "gte", "lte")
|
||||
|
||||
def _get_next_neighbor(self, queryset):
|
||||
def _get_previous_neighbor(self, queryset):
|
||||
queryset = queryset.filter(self._or(self._get_prev_neighbor_filters(queryset)))
|
||||
try:
|
||||
return queryset.filter(self._get_next_neighbor_filters(queryset))[0]
|
||||
return queryset.reverse()[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def _get_next_neighbor(self, queryset):
|
||||
queryset = queryset.filter(self._or(self._get_next_neighbor_filters(queryset)))
|
||||
try:
|
||||
return queryset[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
|
|
@ -81,6 +81,157 @@ class Issue(NeighborsMixin, WatchedMixin, BlockedMixin):
|
|||
def __str__(self):
|
||||
return "({1}) {0}".format(self.ref, self.subject)
|
||||
|
||||
def _get_order_by(self, queryset):
|
||||
ordering = self._get_queryset_order_by(queryset)
|
||||
if ordering:
|
||||
main_order = ordering[0]
|
||||
need_extra_ordering = ("severity", "-severity", "owner__first_name",
|
||||
"-owner__first_name", "status", "-status", "priority",
|
||||
"-priority", "assigned_to__first_name",
|
||||
"-assigned_to__first_name")
|
||||
if main_order in need_extra_ordering:
|
||||
ordering += self._meta.ordering
|
||||
|
||||
return ordering
|
||||
|
||||
def _get_prev_neighbor_filters(self, queryset):
|
||||
conds = super()._get_prev_neighbor_filters(queryset)
|
||||
main_order = queryset.query.order_by[0]
|
||||
if main_order == "severity":
|
||||
conds = [{"severity__order__lt": self.severity.order},
|
||||
{"severity__order": self.severity.order,
|
||||
"created_date__lt": self.created_date}]
|
||||
elif main_order == "-severity":
|
||||
conds = [{"severity__order__gt": self.severity.order},
|
||||
{"severity__order": self.severity.order,
|
||||
"created_date__lt": self.created_date}]
|
||||
elif main_order == "status":
|
||||
conds = [{"status__order__lt": self.status.order},
|
||||
{"status__order": self.status.order,
|
||||
"created_date__lt": self.created_date}]
|
||||
elif main_order == "-status":
|
||||
conds = [{"status__order__gt": self.status.order},
|
||||
{"status__order": self.status.order,
|
||||
"created_date__lt": self.created_date}]
|
||||
elif main_order == "priority":
|
||||
conds = [{"priority__order__lt": self.priority.order},
|
||||
{"priority__order": self.priority.order,
|
||||
"created_date__lt": self.created_date}]
|
||||
elif main_order == "-priority":
|
||||
conds = [{"priority__order__gt": self.priority.order},
|
||||
{"priority__order": self.priority.order,
|
||||
"created_date__lt": self.created_date}]
|
||||
elif main_order == "owner__first_name":
|
||||
conds = [{"owner__first_name": self.owner.first_name,
|
||||
"owner__last_name": self.owner.last_name,
|
||||
"created_date__lt": self.created_date},
|
||||
{"owner__first_name": self.owner.first_name,
|
||||
"owner__last_name__lt": self.owner.last_name},
|
||||
{"owner__first_name__lt": self.owner.first_name}]
|
||||
elif main_order == "-owner__first_name":
|
||||
conds = [{"owner__first_name": self.owner.first_name,
|
||||
"owner__last_name": self.owner.last_name,
|
||||
"created_date__lt": self.created_date},
|
||||
{"owner__first_name": self.owner.first_name,
|
||||
"owner__last_name__gt": self.owner.last_name},
|
||||
{"owner__first_name__gt": self.owner.first_name}]
|
||||
elif main_order == "assigned_to__first_name":
|
||||
if self.assigned_to:
|
||||
conds = [{"assigned_to__first_name": self.assigned_to.first_name,
|
||||
"assigned_to__last_name": self.assigned_to.last_name,
|
||||
"created_date__lt": self.created_date},
|
||||
{"assigned_to__first_name": self.assigned_to.first_name,
|
||||
"assigned_to__last_name__lt": self.assigned_to.last_name},
|
||||
{"assigned_to__first_name__lt": self.assigned_to.first_name}]
|
||||
else:
|
||||
conds = [{"assigned_to__isnull": True,
|
||||
"created_date__lt": self.created_date},
|
||||
{"assigned_to__isnull": False}]
|
||||
elif main_order == "-assigned_to__first_name":
|
||||
if self.assigned_to:
|
||||
conds = [{"assigned_to__first_name": self.assigned_to.first_name,
|
||||
"assigned_to__last_name": self.assigned_to.last_name,
|
||||
"created_date__lt": self.created_date},
|
||||
{"assigned_to__first_name": self.assigned_to.first_name,
|
||||
"assigned_to__last_name__gt": self.assigned_to.last_name},
|
||||
{"assigned_to__first_name__gt": self.assigned_to.first_name},
|
||||
{"assigned_to__isnull": True}]
|
||||
else:
|
||||
conds = [{"assigned_to__isnull": True,
|
||||
"created_date__lt": self.created_date},
|
||||
{"assigned_to__isnull": False}]
|
||||
|
||||
return conds
|
||||
|
||||
def _get_next_neighbor_filters(self, queryset):
|
||||
conds = super()._get_next_neighbor_filters(queryset)
|
||||
ordering = queryset.query.order_by
|
||||
main_order = ordering[0]
|
||||
if main_order == "severity":
|
||||
conds = [{"severity__order__gt": self.severity.order},
|
||||
{"severity__order": self.severity.order,
|
||||
"created_date__gt": self.created_date}]
|
||||
elif main_order == "-severity":
|
||||
conds = [{"severity__order__lt": self.severity.order},
|
||||
{"severity__order": self.severity.order,
|
||||
"created_date__gt": self.created_date}]
|
||||
elif main_order == "status":
|
||||
conds = [{"status__order__gt": self.status.order},
|
||||
{"status__order": self.status.order,
|
||||
"created_date__gt": self.created_date}]
|
||||
elif main_order == "-status":
|
||||
conds = [{"status__order__lt": self.status.order},
|
||||
{"status__order": self.status.order,
|
||||
"created_date__gt": self.created_date}]
|
||||
elif main_order == "priority":
|
||||
conds = [{"priority__order__gt": self.priority.order},
|
||||
{"priority__order": self.priority.order,
|
||||
"created_date__gt": self.created_date}]
|
||||
elif main_order == "-priority":
|
||||
conds = [{"priority__order__lt": self.priority.order},
|
||||
{"priority__order": self.priority.order,
|
||||
"created_date__gt": self.created_date}]
|
||||
elif main_order == "owner__first_name":
|
||||
conds = [{"owner__first_name": self.owner.first_name,
|
||||
"owner__last_name": self.owner.last_name,
|
||||
"created_date__gt": self.created_date},
|
||||
{"owner__first_name": self.owner.first_name,
|
||||
"owner__last_name__gt": self.owner.last_name},
|
||||
{"owner__first_name__gt": self.owner.first_name}]
|
||||
elif main_order == "-owner__first_name":
|
||||
conds = [{"owner__first_name": self.owner.first_name,
|
||||
"owner__last_name": self.owner.last_name,
|
||||
"created_date__gt": self.created_date},
|
||||
{"owner__first_name": self.owner.first_name,
|
||||
"owner__last_name__lt": self.owner.last_name},
|
||||
{"owner__first_name__lt": self.owner.first_name}]
|
||||
elif main_order == "assigned_to__first_name":
|
||||
if self.assigned_to:
|
||||
conds = [{"assigned_to__first_name": self.assigned_to.first_name,
|
||||
"assigned_to__last_name": self.assigned_to.last_name,
|
||||
"created_date__gt": self.created_date},
|
||||
{"assigned_to__first_name": self.assigned_to.first_name,
|
||||
"assigned_to__last_name__gt": self.assigned_to.last_name},
|
||||
{"assigned_to__first_name__gt": self.assigned_to.first_name},
|
||||
{"assigned_to__isnull": True}]
|
||||
else:
|
||||
conds = [{"assigned_to__isnull": True,
|
||||
"created_date__gt": self.created_date}]
|
||||
elif main_order == "-assigned_to__first_name":
|
||||
if self.assigned_to:
|
||||
conds = [{"assigned_to__first_name": self.assigned_to.first_name,
|
||||
"assigned_to__last_name": self.assigned_to.last_name,
|
||||
"created_date__gt": self.created_date},
|
||||
{"assigned_to__first_name": self.assigned_to.first_name,
|
||||
"assigned_to__last_name__lt": self.assigned_to.last_name},
|
||||
{"assigned_to__first_name__lt": self.assigned_to.first_name}]
|
||||
else:
|
||||
conds = [{"assigned_to__isnull": True,
|
||||
"created_date__gt": self.created_date},
|
||||
{"assigned_to__isnull": False}]
|
||||
|
||||
return conds
|
||||
|
||||
@property
|
||||
def is_closed(self):
|
||||
return self.status.is_closed
|
||||
|
|
|
@ -113,12 +113,14 @@ class UserStory(NeighborsMixin, WatchedMixin, BlockedMixin, models.Model):
|
|||
return "<UserStory %s>" % (self.id)
|
||||
|
||||
def _get_prev_neighbor_filters(self, queryset):
|
||||
return self._or([{"order__lt": "{obj.order}"},
|
||||
{"order__lte": "{obj.order}", "ref__lt": "{obj.ref}"}])
|
||||
conds = [{"order__lt": "{obj.order}"},
|
||||
{"order__lte": "{obj.order}", "ref__lt": "{obj.ref}"}]
|
||||
return conds
|
||||
|
||||
def _get_next_neighbor_filters(self, queryset):
|
||||
return self._or([{"order__gt": "{obj.order}"},
|
||||
{"order__gte": "{obj.order}", "ref__gt": "{obj.ref}"}])
|
||||
conds = [{"order__gt": "{obj.order}"},
|
||||
{"order__gte": "{obj.order}", "ref__gt": "{obj.ref}"}]
|
||||
return conds
|
||||
|
||||
def get_role_points(self):
|
||||
return self.role_points
|
||||
|
|
Loading…
Reference in New Issue