[PATCH 3/4] models, templates: Add patch relations
Daniel Axtens
dja at axtens.net
Tue Feb 11 16:23:59 AEDT 2020
>> + 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']
>>
>>
>> + at 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)
>>
>>
>> + at 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
More information about the Patchwork
mailing list