get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/710291/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 710291,
    "url": "http://patchwork.ozlabs.org/api/patches/710291/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/patchwork/patch/20170102212347.18089-1-stephen@that.guru/",
    "project": {
        "id": 16,
        "url": "http://patchwork.ozlabs.org/api/projects/16/?format=api",
        "name": "Patchwork",
        "link_name": "patchwork",
        "list_id": "patchwork.lists.ozlabs.org",
        "list_email": "patchwork@lists.ozlabs.org",
        "web_url": "http://jk.ozlabs.org/projects/patchwork/",
        "scm_url": "git://github.com/getpatchwork/patchwork",
        "webscm_url": "https://github.com/getpatchwork/patchwork",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170102212347.18089-1-stephen@that.guru>",
    "list_archive_url": null,
    "date": "2017-01-02T21:23:45",
    "name": "[v2,1/3] REST: Integrate django-filter support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "f7edcb2b4f2defbcd64ce044c343107f48b7a766",
    "submitter": {
        "id": 69991,
        "url": "http://patchwork.ozlabs.org/api/people/69991/?format=api",
        "name": "Stephen Finucane",
        "email": "stephen@that.guru"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/patchwork/patch/20170102212347.18089-1-stephen@that.guru/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/710291/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/710291/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "patchwork@lists.ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "patchwork@lists.ozlabs.org"
        ],
        "Received": [
            "from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3tsqpD5560z9sf9\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue,  3 Jan 2017 08:24:20 +1100 (AEDT)",
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3tsqpD1T1gzDqGZ\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue,  3 Jan 2017 08:24:20 +1100 (AEDT)",
            "from cat.maple.relay.mailchannels.net\n\t(cat.maple.relay.mailchannels.net [23.83.214.31])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3tsqnx2RqCzDqDt\n\tfor <patchwork@lists.ozlabs.org>;\n\tTue,  3 Jan 2017 08:24:05 +1100 (AEDT)",
            "from relay.mailchannels.net (localhost [127.0.0.1])\n\tby relay.mailchannels.net (Postfix) with ESMTP id B162520E09;\n\tMon,  2 Jan 2017 21:24:01 +0000 (UTC)",
            "from one.mxroute.com (ip-10-120-4-226.us-west-2.compute.internal\n\t[10.120.4.226])\n\tby relay.mailchannels.net (Postfix) with ESMTPA id CE4CC20639;\n\tMon,  2 Jan 2017 21:24:00 +0000 (UTC)",
            "from one.mxroute.com ([TEMPUNAVAIL]. [10.29.28.91])\n\t(using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384)\n\tby 0.0.0.0:2500 (trex/5.7.8); Mon, 02 Jan 2017 21:24:01 +0000"
        ],
        "Authentication-Results": [
            "ozlabs.org;\n\tdkim=fail reason=\"key not found in DNS\" (0-bit key;\n\tunprotected) header.d=that.guru header.i=@that.guru\n\theader.b=\"Vcxuwfwn\"; dkim-atps=neutral",
            "lists.ozlabs.org;\n\tdkim=fail reason=\"key not found in DNS\" (0-bit key;\n\tunprotected) header.d=that.guru header.i=@that.guru\n\theader.b=\"Vcxuwfwn\"; dkim-atps=neutral",
            "lists.ozlabs.org;\n\tdkim=fail reason=\"key not found in DNS\" (0-bit key;\n\tunprotected) header.d=that.guru header.i=@that.guru\n\theader.b=\"Vcxuwfwn\"; dkim-atps=neutral"
        ],
        "X-Sender-Id": [
            "mxroute|x-authuser|stephen@that.guru",
            "mxroute|x-authuser|stephen@that.guru"
        ],
        "X-MC-Relay": "Neutral",
        "X-MailChannels-SenderId": "mxroute|x-authuser|stephen@that.guru",
        "X-MailChannels-Auth-Id": "mxroute",
        "X-MC-Loop-Signature": "1483392241197:1633679644",
        "X-MC-Ingress-Time": "1483392241196",
        "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=that.guru;\n\ts=default;\n\th=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version\n\t:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tIn-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:\n\tList-Post:List-Owner:List-Archive;\n\tbh=WBcd9lrZqv67jW7nMpJF4R6M7b/MSfMs54hoDjE9CdA=;\n\tb=Vcxuwfwn+CRE2xgG3m8+iH18Mc\n\t1rBhCuuWmArdpvqaKMPLK8fMfgL3ZEV051XVOGgq7Mg1+3Uf28ctA+ijfTnSAJHglxsMGhafVAHw5\n\tpvUSpf/MjN0CxTLWTDKiDFFpFQ5rHG/tUcfoaA8SxcRo2elzUm4VfF83NYtsNSVzHIj3e7+NUMLH9\n\tQIFrACTUMr705FYoCK/dVG1pf25kdss8nYBK8N8sSM3pc2ZNbga6J2z0P7HZ7jczJHI6oAWo1V1po\n\t4NIfhJcVH2+0rcu0Ha1orM1BYW/p7BBKTg1vte3Y1AcldppEv7Ez7kFNgfN0tNgNW6RRlAF2+A4OK\n\tJOYKi4WA==;",
        "From": "Stephen Finucane <stephen@that.guru>",
        "To": "patchwork@lists.ozlabs.org",
        "Subject": "[PATCH v2 1/3] REST: Integrate django-filter support",
        "Date": "Mon,  2 Jan 2017 21:23:45 +0000",
        "Message-Id": "<20170102212347.18089-1-stephen@that.guru>",
        "X-Mailer": "git-send-email 2.9.3",
        "X-AuthUser": "stephen@that.guru",
        "X-BeenThere": "patchwork@lists.ozlabs.org",
        "X-Mailman-Version": "2.1.23",
        "Precedence": "list",
        "List-Id": "Patchwork development <patchwork.lists.ozlabs.org>",
        "List-Unsubscribe": "<https://lists.ozlabs.org/options/patchwork>,\n\t<mailto:patchwork-request@lists.ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.ozlabs.org/pipermail/patchwork/>",
        "List-Post": "<mailto:patchwork@lists.ozlabs.org>",
        "List-Help": "<mailto:patchwork-request@lists.ozlabs.org?subject=help>",
        "List-Subscribe": "<https://lists.ozlabs.org/listinfo/patchwork>,\n\t<mailto:patchwork-request@lists.ozlabs.org?subject=subscribe>",
        "Cc": "Andrew Donnellan <andrew.donnellan@au1.ibm.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org",
        "Sender": "\"Patchwork\"\n\t<patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>"
    },
    "content": "This mostly works out of the box, thanks to Django REST Framework.\nMostly unique fields, like name or email, are excluded as these will be\nhandled separately.\n\nSigned-off-by: Stephen Finucane <stephen@that.guru>\nCc: Andrew Donnellan <andrew.donnellan@au1.ibm.com>\nCc: Russell Currey <ruscur@russell.cc>\n---\nv2:\n- Move new filters to 'api/filters' instead of 'filters'\n- Add 'project' filter to '/cover' and '/patch' endpoints\n- Bump django-filter to 1.0\n---\n patchwork/api/check.py     |  2 ++\n patchwork/api/cover.py     |  2 ++\n patchwork/api/filters.py   | 62 ++++++++++++++++++++++++++++++++++++++++++++++\n patchwork/api/patch.py     |  2 ++\n patchwork/api/series.py    |  3 ++-\n patchwork/settings/base.py |  6 ++++-\n requirements-prod.txt      |  1 +\n requirements-test.txt      |  1 +\n 8 files changed, 77 insertions(+), 2 deletions(-)\n create mode 100644 patchwork/api/filters.py",
    "diff": "diff --git a/patchwork/api/check.py b/patchwork/api/check.py\nindex a66106e..dcdc5c5 100644\n--- a/patchwork/api/check.py\n+++ b/patchwork/api/check.py\n@@ -27,6 +27,7 @@ from rest_framework.serializers import HyperlinkedModelSerializer\n from rest_framework.serializers import HyperlinkedIdentityField\n \n from patchwork.api.base import MultipleFieldLookupMixin\n+from patchwork.api.filters import CheckFilter\n from patchwork.models import Check\n from patchwork.models import Patch\n \n@@ -89,6 +90,7 @@ class CheckMixin(object):\n \n     queryset = Check.objects.prefetch_related('patch', 'user')\n     serializer_class = CheckSerializer\n+    filter_class = CheckFilter\n \n \n class CheckListCreate(CheckMixin, ListCreateAPIView):\ndiff --git a/patchwork/api/cover.py b/patchwork/api/cover.py\nindex b440d51..6374ce9 100644\n--- a/patchwork/api/cover.py\n+++ b/patchwork/api/cover.py\n@@ -26,6 +26,7 @@ from rest_framework.serializers import HyperlinkedModelSerializer\n from rest_framework.serializers import HyperlinkedRelatedField\n from rest_framework.serializers import SerializerMethodField\n \n+from patchwork.api.filters import CoverLetterFilter\n from patchwork.models import CoverLetter\n \n \n@@ -66,6 +67,7 @@ class CoverLetterList(ListAPIView):\n     \"\"\"List cover letters.\"\"\"\n \n     serializer_class = CoverLetterListSerializer\n+    filter_class = CoverLetterFilter\n \n     def get_queryset(self):\n         qs = CoverLetter.objects.all().prefetch_related('series')\\\ndiff --git a/patchwork/api/filters.py b/patchwork/api/filters.py\nnew file mode 100644\nindex 0000000..5f237b4\n--- /dev/null\n+++ b/patchwork/api/filters.py\n@@ -0,0 +1,62 @@\n+# Patchwork - automated patch tracking system\n+# Copyright (C) 2017 Stephen Finucane <stephen@that.guru>\n+#\n+# This file is part of the Patchwork package.\n+#\n+# Patchwork is free software; you can redistribute it and/or modify\n+# it under the terms of the GNU General Public License as published by\n+# the Free Software Foundation; either version 2 of the License, or\n+# (at your option) any later version.\n+#\n+# Patchwork is distributed in the hope that it will be useful,\n+# but WITHOUT ANY WARRANTY; without even the implied warranty of\n+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+# GNU General Public License for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with Patchwork; if not, write to the Free Software\n+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n+\n+from django_filters import FilterSet\n+from django_filters import IsoDateTimeFilter\n+\n+from patchwork.models import Check\n+from patchwork.models import CoverLetter\n+from patchwork.models import Patch\n+from patchwork.models import Series\n+\n+\n+class TimestampMixin(object):\n+\n+    # TODO(stephenfin): These should filter on a 'updated_at' field instead\n+    before = IsoDateTimeFilter(name='date', lookup_expr='lt')\n+    since = IsoDateTimeFilter(name='date', lookup_expr='gte')\n+\n+\n+class SeriesFilter(TimestampMixin, FilterSet):\n+\n+    class Meta:\n+        model = Series\n+        fields = ('submitter',)\n+\n+\n+class CoverLetterFilter(TimestampMixin, FilterSet):\n+\n+    class Meta:\n+        model = CoverLetter\n+        fields = ('project', 'series', 'submitter')\n+\n+\n+class PatchFilter(FilterSet):\n+\n+    class Meta:\n+        model = Patch\n+        fields = ('project', 'series', 'submitter', 'delegate', 'state',\n+                  'archived')\n+\n+\n+class CheckFilter(TimestampMixin, FilterSet):\n+\n+    class Meta:\n+        model = Check\n+        fields = ('user', 'state', 'context')\ndiff --git a/patchwork/api/patch.py b/patchwork/api/patch.py\nindex e78f683..d12464f 100644\n--- a/patchwork/api/patch.py\n+++ b/patchwork/api/patch.py\n@@ -29,6 +29,7 @@ from rest_framework.serializers import SerializerMethodField\n \n from patchwork.api.base import PatchworkPermission\n from patchwork.api.base import STATE_CHOICES\n+from patchwork.api.filters import PatchFilter\n from patchwork.models import Patch\n from patchwork.models import State\n \n@@ -117,6 +118,7 @@ class PatchList(ListAPIView):\n \n     permission_classes = (PatchworkPermission,)\n     serializer_class = PatchListSerializer\n+    filter_class = PatchFilter\n \n     def get_queryset(self):\n         return Patch.objects.all().with_tag_counts()\\\ndiff --git a/patchwork/api/series.py b/patchwork/api/series.py\nindex ade37fb..edde9a9 100644\n--- a/patchwork/api/series.py\n+++ b/patchwork/api/series.py\n@@ -22,6 +22,7 @@ from rest_framework.generics import RetrieveAPIView\n from rest_framework.serializers import HyperlinkedModelSerializer\n \n from patchwork.api.base import PatchworkPermission\n+from patchwork.api.filters import SeriesFilter\n from patchwork.models import Series\n \n \n@@ -54,7 +55,7 @@ class SeriesMixin(object):\n class SeriesList(SeriesMixin, ListAPIView):\n     \"\"\"List series.\"\"\"\n \n-    pass\n+    filter_class = SeriesFilter\n \n \n class SeriesDetail(SeriesMixin, RetrieveAPIView):\ndiff --git a/patchwork/settings/base.py b/patchwork/settings/base.py\nindex b7b10c3..35b85c7 100644\n--- a/patchwork/settings/base.py\n+++ b/patchwork/settings/base.py\n@@ -133,7 +133,8 @@ try:\n     import rest_framework  # NOQA\n \n     INSTALLED_APPS += [\n-        'rest_framework'\n+        'rest_framework',\n+        'django_filters',\n     ]\n except ImportError:\n     pass\n@@ -143,6 +144,9 @@ REST_FRAMEWORK = {\n     'DEFAULT_VERSIONING_CLASS':\n         'rest_framework.versioning.NamespaceVersioning',\n     'DEFAULT_PAGINATION_CLASS': 'patchwork.api.base.LinkHeaderPagination',\n+    'DEFAULT_FILTER_BACKENDS': (\n+        'django_filters.rest_framework.DjangoFilterBackend',\n+    ),\n }\n \n #\ndiff --git a/requirements-prod.txt b/requirements-prod.txt\nindex 64d4339..a56a62f 100644\n--- a/requirements-prod.txt\n+++ b/requirements-prod.txt\n@@ -1,4 +1,5 @@\n Django>=1.8,<1.11\n djangorestframework>=3.5,<3.6\n+django-filter>=1.0,<1.1\n psycopg2>2.6,<2.7\n sqlparse\ndiff --git a/requirements-test.txt b/requirements-test.txt\nindex aa756f5..55713ef 100644\n--- a/requirements-test.txt\n+++ b/requirements-test.txt\n@@ -2,3 +2,4 @@ mysqlclient>=1.3,<1.4  # replace this with psycopg2 for a PostgreSQL backend\n django-debug-toolbar==1.6\n python-dateutil>2.0,<3.0\n selenium>=3.0,<3.1\n+django-filter>=1.0,<1.1\n",
    "prefixes": [
        "v2",
        "1/3"
    ]
}