- Python (2.7, 3.3 - 3.5)
-- Django (1.6 - 1.11)
+- Django (1.8 - 1.11)
- Django REST Framework (3.2 - 3.6)
-- Django Filters (0.11 - 1.0)
+- Django Filters (1.0)
Development Installation
------------------------
Upgrade Your Database
---------------------
-Migrations of the database can be tricky. Prior to `v1.0.0`__, database
-migrations were provided by way of manual, SQL migration scripts. After this
-release, Patchwork moved to support `Django migrations`__. If you are
-upgrading from `v1.0.0` or later, it is likely that you can rely entirely on
-the later to bring your database up-to-date. This can be done like so:
+New versions of Patchwork may provide a number of schema and/or data migrations
+which must be applied before starting the instance. To do this, run the
+*migrate* management command:
.. code-block:: shell
$ ./manage.py migrate
-However, there are a number of scenarios in which you may need to fall back to
-the provided SQL migrations or provide your own:
+For more information on migrations, refer to `the Django documentation`__.
-* You are using Django < 1.6
-
- Patchwork supports Django 1.6. However, Django Migrations was added in 1.7
- and is `not available for previous versions`__. As such, you must continue to
- use manual migrations or upgrade your version of Django. For many of the
- migrations, this can be done automatically:
-
- .. code-block:: shell
-
- $ ./manage.py sqlmigrate patchwork 0003_add_check_model
-
- However, this only works for schema migrations. For data migrations,
- however, this will fail. In this cases, these migrations will need to be
- handwritten.
-
-* You are using Django > 1.6, but upgrading from Patchwork < 1.0.0
-
- Patchwork only started providing migrations in `v1.0.0`. SQL migrations are
- provided for versions prior to this and must be applied to get the database
- to the "initial" state that Django migrations expects.
-
-* You have diverged from upstream Patchwork
-
- If you have applied custom patches that change the database models, the
- database in an "inconsistent state" and the provided migrations will likely
- fail to apply.
-
-Steps to handle the latter two of these are described below.
-
-__ https://github.com/getpatchwork/patchwork/releases/tag/v1.0.0
-__ https://docs.djangoproject.com/en/1.8/topics/migrations/
-__ http://blog.allenap.me/2015/05/south-south-2-and-django-migrations.html
-
-Upgrading a pre-v1.0.0 Patchwork instance
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The process for this type of upgrade is quite simple: upgrade using manual SQL
-upgrades until better options become available. As such, you should apply all
-unapplied SQL migrations that are not duplicated by Django migrations. Once
-such duplication occurs, rely on the Django migrations only and continue to do
-so going forward.
-
-Upgrading a "diverged" Patchwork instance
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This type of upgrade is a little trickier. There are two options you can take:
-
-1. Bring your Patchwork instance back in sync with upstream
-
-2. Provide your own migrations
-
-The former option is particularly suitable if you decide to upstream your
-change or decide it's not valuable enough to retain. This will require either
-reworking any migrations that exist prior to your feature being upstreamed, or
-deleting any added database fields and tables, respectively. In both cases,
-manually, hand-written SQL migrations will be required to get the databse into
-a consistent state (remember: **backup**!). Once this is done, you can resume
-using the upstream-provided migrations, ensuring any Django migrations that you
-may have skipped are not applied again:
-
-.. code-block:: shell
-
- $ ./manage.py migrate 000x-abc --fake # when 000x-abc is last "skippable"
-
-It's worth adding that with the databases now back in sync it should be
-possible to return to using upstream code rather than maintaining a fork.
-
-The latter option is best chosen if you wish to retain the aforementioned fork.
-How you do this depends on the extensiveness of your changes, but getting the
-latest version of Patchwork, deleting the provided migrations, applying any
-patches you may have and regenerating the migrations seems like the best
-option.
-
-.. note::
-
- To prevent the latter case above from occurring, we'd ask that you submit
- any patches you may have to the upstream Patchwork so that the wider
- community can benefit from this new functionality.
+__ https://docs.djangoproject.com/en/1.11/topics/migrations/
.. code-block:: shell
- $ docker-compose run --rm web --quick-tox -e py27-django17 \
+ $ docker-compose run --rm web --quick-tox -e py27-django18 \
patchwork.tests.test_bundles
To run all tests, including Selenium UI interaction tests, using only the
import email.parser
-import django
from rest_framework.generics import ListAPIView
from rest_framework.generics import RetrieveAPIView
from rest_framework.serializers import HyperlinkedModelSerializer
ordering = 'id'
def get_queryset(self):
- qs = CoverLetter.objects.all().prefetch_related('series')\
- .select_related('project', 'submitter')
-
- # FIXME(stephenfin): This causes issues with Django 1.6 for whatever
- # reason. Suffer the performance hit on those versions.
- if django.VERSION >= (1, 7):
- qs.defer('content', 'headers')
-
- return qs
+ return CoverLetter.objects.all().prefetch_related('series')\
+ .select_related('project', 'submitter')\
+ .defer('content', 'headers')
class CoverLetterDetail(RetrieveAPIView):
from django_filters import ModelChoiceFilter
from django.forms import ModelChoiceField
-from patchwork.compat import LOOKUP_FIELD
from patchwork.models import Bundle
from patchwork.models import Check
from patchwork.models import CoverLetter
class TimestampMixin(FilterSet):
# TODO(stephenfin): These should filter on a 'updated_at' field instead
- before = IsoDateTimeFilter(name='date', **{LOOKUP_FIELD: 'lt'})
- since = IsoDateTimeFilter(name='date', **{LOOKUP_FIELD: 'gte'})
+ before = IsoDateTimeFilter(name='date', lookup_expr='lt')
+ since = IsoDateTimeFilter(name='date', lookup_expr='gte')
class ProjectChoiceField(ModelChoiceField):
'incorrect_type': _('Incorrect type. Expected string value, received '
'{data_type}.'),
}
- queryset = '' # django 1.6, rest_framework 3.2 require this
def to_internal_value(self, data):
try:
ordering = 'id'
def get_queryset(self):
- # TODO(stephenfin): Does the defer here cause issues with Django 1.6
- # (like /cover)?
return Patch.objects.all()\
.prefetch_related('series', 'check_set')\
.select_related('project', 'state', 'submitter', 'delegate')\
from django.conf import settings
-# render_to_string
-#
-# The render_to_string function no longer accepts the dictionary and
-# context_instance parameters in Django 1.10.
-#
-# https://docs.djangoproject.com/en/dev/releases/1.8/
-
-if django.VERSION >= (1, 8):
- from django.template.loader import render_to_string # noqa
-else:
- from django.template import loader # noqa
- from django.template import RequestContext # noqa
-
- def render_to_string(template_name, context=None, request=None):
- context_instance = RequestContext(request) if request else None
- return loader.render_to_string(template_name, context,
- context_instance)
-
-
# DjangoFilterBackend
#
# The DjangoFilterBackend was provided in Django REST Framework from 3.0 to
from rest_framework.filters import DjangoFilterBackend # noqa
-# LOOKUP_FIELD
-#
-# The django-filter library uses the 'lookup_expr' attribute to determine which
-# lookup type to use, e.g. exact, gt, lt etc. However, until 0.13 this was
-# called 'lookup_type', and 0.13 supported both but gave a deprecation warning.
-# We need to support these versions for use with older versions of DRF.
-#
-# https://github.com/carltongibson/django-filter/blob/v0.13/django_filters\
-# /filters.py#L35-L36
-if settings.ENABLE_REST_API:
- import django_filters # noqa
-
- if django_filters.VERSION >= (1, 0):
- LOOKUP_FIELD = 'lookup_expr'
- else:
- LOOKUP_FIELD = 'lookup_type'
-
-
# reverse, reverse_lazy
#
# The reverse and reverse_lazy functions have been moved to django.urls in
def save(self, *args, **kwargs):
super(Comment, self).save(*args, **kwargs)
- # NOTE(stephenfin): Mitigate an issue with Python 3.4 + Django 1.6
- try:
- if hasattr(self.submission, 'patch'):
- self.submission.patch.refresh_tag_counts()
- except Patch.DoesNotExist:
- pass
+ if hasattr(self.submission, 'patch'):
+ self.submission.patch.refresh_tag_counts()
def delete(self, *args, **kwargs):
super(Comment, self).delete(*args, **kwargs)
on_delete=models.CASCADE)
last_modified = models.DateTimeField(default=datetime.datetime.now)
orig_state = models.ForeignKey(State, on_delete=models.CASCADE)
-
-
-if django.VERSION < (1, 7):
- # We don't have support for AppConfig in Django 1.6.x
- import patchwork.signals # noqa
from django.core.mail import EmailMessage
from django.db.models import Count
from django.db.models import Q
+from django.template.loader import render_to_string
-from patchwork.compat import render_to_string
from patchwork.models import EmailConfirmation
from patchwork.models import EmailOptout
from patchwork.models import PatchChangeNotification
{% load project %}
{% load static %}
-{% load cycle from compat %}
-
{% include "patchwork/filters.html" %}
{% include "patchwork/pagination.html" %}
{% extends "base.html" %}
-{% load cycle from compat %}
{% block title %}Project List{% endblock %}
{% block body %}
+++ /dev/null
-# Patchwork - automated patch tracking system
-# Copyright (C) 2016 Stephen Finucane <stephen@that.guru>
-#
-# This file is part of the Patchwork package.
-#
-# Patchwork is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# Patchwork is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Patchwork; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-"""Compatibility wrappers for various Django versions."""
-
-import django
-from django.template import defaulttags
-from django.template import Library
-
-
-register = Library()
-
-
-# cycle
-#
-# The cycle template tag enables auto-escaping by default in 1.8, with
-# deprecations enabled in 1.7. A 'future' library is provided in 1.6
-# to mitigate this, but it is removed in 1.10. Provide our own version
-# of 'future' to ensure this works in all versions of Django supported.
-#
-# https://docs.djangoproject.com/en/dev/releases/1.6/
-# https://docs.djangoproject.com/en/dev/releases/1.10/
-
-@register.tag
-def cycle(parser, token):
- if django.VERSION < (1, 8):
- return defaulttags.cycle(parser, token, escape=True)
- else:
- return defaulttags.cycle(parser, token)
import os
import time
-try:
- from django.contrib.staticfiles.testing import StaticLiveServerTestCase
-except: # Django < 1.7
- from django.test import LiveServerTestCase as StaticLiveServerTestCase
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium.common.exceptions import (
NoSuchElementException, StaleElementReferenceException,
TimeoutException)
from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render
+from django.template.loader import render_to_string
-from patchwork.compat import render_to_string
from patchwork.compat import reverse
from patchwork.forms import EmailForm
from patchwork.models import EmailConfirmation
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.shortcuts import render
+from django.template.loader import render_to_string
-from patchwork.compat import render_to_string
from patchwork.compat import reverse
from patchwork.filters import DelegateFilter
from patchwork.forms import EmailForm
--- /dev/null
+---
+upgrade:
+ - |
+ Django 1.6 and 1.7 are no longer supported. These are no longer supported
+ upstream and most distributions provide a newer version.
+ - |
+ django-filter 0.11 is no longer supported. This was only used with Django
+ 1.6 and 1.7 and is not compatible with any version supported by Patchwork.
[tox]
minversion = 2.0
-envlist = pep8,py{27,34}-django{16,17,18,19,110,111},py35-django{18,19,110,111}
+envlist = pep8,py{27,34,35}-django{18,19,110,111}
skipsdist = True
[testenv]
deps =
-r{toxinidir}/requirements-test.txt
- django16: django>=1.6,<1.7
- django16: djangorestframework>=3.2,<3.3
- django16: django-filter>=0.11,<0.12
- django17: django>=1.7,<1.8
- django17: djangorestframework>=3.3,<3.4
- django17: django-filter>=0.11,<0.12
django18: django>=1.8,<1.9
django19: django>=1.9,<1.10
django110: django>=1.10,<1.11