>> + related = models.ForeignKey( >> + 'PatchRelation', null=True, blank=True, on_delete=models.SET_NULL, >> + related_name='patches', related_query_name='patch') >> + > > I wonder if we need to make this a many-to-many to patch through > patchrelation? I'm struggling to get this to prefetch_related or > select_related properly: the best I can do atm is to prefetch_related on > 'related__patches__project' which is super gross (and might be fetching > every project?)
Nevermind, we don't want a django-style many-to-many, it's just a hard problem. Regards, Daniel > > Regards, > Daniel > >> objects = PatchManager() >> >> @staticmethod >> @@ -863,6 +869,19 @@ class BundlePatch(models.Model): >> ordering = ['order'] >> >> >> +@python_2_unicode_compatible >> +class PatchRelation(models.Model): >> + >> + def __str__(self): >> + patches = self.patches.all() >> + if not patches: >> + return '<Empty>' >> + name = ', '.join(patch.name for patch in patches[:10]) >> + if len(name) > 60: >> + name = name[:60] + '...' >> + return name >> + >> + >> @python_2_unicode_compatible >> class Check(models.Model): >> >> @@ -928,6 +947,7 @@ class Event(models.Model): >> CATEGORY_PATCH_COMPLETED = 'patch-completed' >> CATEGORY_PATCH_STATE_CHANGED = 'patch-state-changed' >> CATEGORY_PATCH_DELEGATED = 'patch-delegated' >> + CATEGORY_PATCH_RELATION_CHANGED = 'patch-relation-changed' >> CATEGORY_CHECK_CREATED = 'check-created' >> CATEGORY_SERIES_CREATED = 'series-created' >> CATEGORY_SERIES_COMPLETED = 'series-completed' >> @@ -937,6 +957,7 @@ class Event(models.Model): >> (CATEGORY_PATCH_COMPLETED, 'Patch Completed'), >> (CATEGORY_PATCH_STATE_CHANGED, 'Patch State Changed'), >> (CATEGORY_PATCH_DELEGATED, 'Patch Delegate Changed'), >> + (CATEGORY_PATCH_RELATION_CHANGED, 'Patch Relation Changed'), >> (CATEGORY_CHECK_CREATED, 'Check Created'), >> (CATEGORY_SERIES_CREATED, 'Series Created'), >> (CATEGORY_SERIES_COMPLETED, 'Series Completed'), >> @@ -952,7 +973,7 @@ class Event(models.Model): >> # event metadata >> >> category = models.CharField( >> - max_length=20, >> + max_length=25, >> choices=CATEGORY_CHOICES, >> db_index=True, >> help_text='The category of the event.') >> @@ -1000,6 +1021,15 @@ class Event(models.Model): >> User, related_name='+', null=True, blank=True, >> on_delete=models.CASCADE) >> >> + # fields for 'patch-relation-changed-changed' events >> + >> + previous_relation = models.ForeignKey( >> + PatchRelation, related_name='+', null=True, blank=True, >> + on_delete=models.CASCADE) >> + current_relation = models.ForeignKey( >> + PatchRelation, related_name='+', null=True, blank=True, >> + on_delete=models.CASCADE) >> + >> # fields or 'patch-check-created' events >> >> created_check = models.ForeignKey( >> diff --git a/patchwork/signals.py b/patchwork/signals.py >> index 73ddfa5e35ee..3a2f0fbdd3a4 100644 >> --- a/patchwork/signals.py >> +++ b/patchwork/signals.py >> @@ -134,6 +134,30 @@ def create_patch_delegated_event(sender, instance, raw, >> **kwargs): >> create_event(instance, orig_patch.delegate, instance.delegate) >> >> >> +@receiver(pre_save, sender=Patch) >> +def create_patch_relation_changed_event(sender, instance, raw, **kwargs): >> + >> + def create_event(patch, before, after): >> + return Event.objects.create( >> + category=Event.CATEGORY_PATCH_RELATION_CHANGED, >> + project=patch.project, >> + actor=getattr(patch, '_edited_by', None), >> + patch=patch, >> + previous_relation=before, >> + current_relation=after) >> + >> + # don't trigger for items loaded from fixtures or new items >> + if raw or not instance.pk: >> + return >> + >> + orig_patch = Patch.objects.get(pk=instance.pk) >> + >> + if orig_patch.related == instance.related: >> + return >> + >> + create_event(instance, orig_patch.related, instance.related) >> + >> + >> @receiver(pre_save, sender=Patch) >> def create_patch_completed_event(sender, instance, raw, **kwargs): >> >> diff --git a/patchwork/templates/patchwork/submission.html >> b/patchwork/templates/patchwork/submission.html >> index 77a2711ab5b4..978559b8726b 100644 >> --- a/patchwork/templates/patchwork/submission.html >> +++ b/patchwork/templates/patchwork/submission.html >> @@ -110,6 +110,43 @@ function toggle_div(link_id, headers_id, label_show, >> label_hide) >> </td> >> </tr> >> {% endif %} >> +{% if submission.related %} >> + <tr> >> + <th>Related</th> >> + <td> >> + <a id="togglerelated" >> + href="javascript:toggle_div('togglerelated', 'related')" >> + >show</a> >> + <div id="related" class="submissionlist" style="display:none;"> >> + <ul> >> + {% for sibling in related_same_project %} >> + <li> >> + {% if sibling.id != submission.id %} >> + <a href="{% url 'patch-detail' project_id=project.linkname >> msgid=sibling.url_msgid %}"> >> + {{ sibling.name|default:"[no subject]"|truncatechars:100 }} >> + </a> >> + {% endif %} >> + </li> >> + {% endfor %} >> + {% if related_different_project %} >> + <a id="togglerelatedoutside" >> + href="javascript:toggle_div('togglerelatedoutside', >> 'relatedoutside', 'show from other projects')" >> + >show from other projects</a> >> + <div id="relatedoutside" class="submissionlist" style="display:none;"> >> + {% for sibling in related_outside %} >> + <li> >> + <a href="{% url 'patch-detail' project_id=sibling.project.linkname >> msgid=sibling.url_msgid %}"> >> + {{ sibling.name|default:"[no subject]"|truncatechars:100 }} >> + </a> (in {{ sibling.project }}) >> + </li> >> + {% endfor %} >> + </div> >> + {% endif %} >> + </ul> >> + </div> >> + </td> >> + </tr> >> +{% endif %} >> </table> >> >> <div class="patchforms"> >> diff --git a/patchwork/views/patch.py b/patchwork/views/patch.py >> index f34053ce57da..e32ff0bff5f5 100644 >> --- a/patchwork/views/patch.py >> +++ b/patchwork/views/patch.py >> @@ -110,12 +110,25 @@ def patch_detail(request, project_id, msgid): >> comments = comments.only('submitter', 'date', 'id', 'content', >> 'submission') >> >> + if patch.related: >> + related_same_project = \ >> + patch.related.patches.only('name', 'msgid', 'project', >> 'related') >> + # avoid a second trip out to the db for info we already have >> + related_different_project = \ >> + [related_patch for related_patch in related_same_project >> + if related_patch.project_id != patch.project_id] >> + else: >> + related_same_project = [] >> + related_different_project = [] >> + >> context['comments'] = comments >> context['checks'] = patch.check_set.all().select_related('user') >> context['submission'] = patch >> context['patchform'] = form >> context['createbundleform'] = createbundleform >> context['project'] = patch.project >> + context['related_same_project'] = related_same_project >> + context['related_different_project'] = related_different_project >> >> return render(request, 'patchwork/submission.html', context) >> >> -- >> 2.20.1 _______________________________________________ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork