diff --git a/.travis.yml b/.travis.yml index 2f84599..aa8568c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,10 @@ language: python python: - 2.7 - - 3.2 - - 3.3 - 3.4 - 3.5 - 3.6 + - 3.7-dev before_install: - pip install coveralls @@ -19,25 +18,20 @@ install: script: make test env: - - DJANGO=1.7.11 - - DJANGO=1.8.17 - - DJANGO=1.9.12 - - DJANGO=1.10.4 + - DJANGO=1.11.15 + - DJANGO=2.0.8 + - DJANGO=2.1 matrix: exclude: - - python: 3.2 - env: DJANGO=1.10.4 - - python: 3.3 - env: DJANGO=1.10.4 - - python: 3.2 - env: DJANGO=1.9.12 - - python: 3.3 - env: DJANGO=1.9.12 - - python: 3.5 - env: DJANGO=1.7.11 - - python: 3.6 - env: DJANGO=1.7.11 + - python: 2.7 + env: DJANGO=2.0.8 + - python: 2.7 + env: DJANGO=2.1 + - python: 3.4 + env: DJANGO=2.1 + - python: 3.7-dev + env: DJANGO=1.11.15 after_success: - coveralls diff --git a/AUTHORS.rst b/AUTHORS.rst index 4a772f6..a62737a 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -11,6 +11,7 @@ Contributors ------------ * Boris Shifrin +* Matheus Cansian Background ---------- diff --git a/HISTORY.rst b/HISTORY.rst index 6955e7d..bd6a0f4 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,6 +6,10 @@ History 0.6.1 (Not released) ++++++++++++++++++++ * Fixed generic primary key bug with `createinitialfieldhistory` command (#20) +* Dropped support for Python 3.2 and 3.3 +* Dropped support for Django 1.7 through 1.10 +* Added support for Python 3.7 +* Added support for Django 2.1 0.6.0 (December 22, 2016) +++++++++++++++++++++++++ diff --git a/README.rst b/README.rst index 003c589..d12aab4 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ django-field-history .. image:: https://coveralls.io/repos/github/grantmcconnaughey/django-field-history/badge.svg?branch=master :target: https://coveralls.io/github/grantmcconnaughey/django-field-history?branch=master -A Django app to track changes to a model field. For Python 2.7/3.2+ and Django 1.7+. +A Django app to track changes to a model field. For Python 2.7/3.4+ and Django 1.11/2.0+. Other similar apps are `django-reversion `_ and `django-simple-history `_, which track *all* model fields. @@ -173,7 +173,7 @@ You will need to also update the ``field_name`` value in all ``FieldHistory`` ob Storing Which User Changed the Field ------------------------------------ -There are two ways to store the user that changed your model field. The simplest way is to use **the logged in user** that made the request. To do this, add the ``FieldHistoryMiddleware`` class to your ``MIDDLEWARE`` setting (in Django 1.10+) or your ``MIDDLEWARE_CLASSES`` setting (in Django 1.7-1.9). +There are two ways to store the user that changed your model field. The simplest way is to use **the logged in user** that made the request. To do this, add the ``FieldHistoryMiddleware`` class to your ``MIDDLEWARE`` setting. .. code-block:: python diff --git a/field_history/json_nested_serializer.py b/field_history/json_nested_serializer.py index 35067df..e2d40d4 100644 --- a/field_history/json_nested_serializer.py +++ b/field_history/json_nested_serializer.py @@ -48,7 +48,7 @@ def serialize(self, queryset, **options): # only one change local_fields -> fields for supporting nested models for field in concrete_model._meta.fields: if field.serialize: - if field.rel is None: + if field.remote_field is None: if self.selected_fields is None or field.attname in self.selected_fields: self.handle_field(obj, field) else: diff --git a/field_history/models.py b/field_history/models.py index 6ee4b1d..4bbc9fa 100644 --- a/field_history/models.py +++ b/field_history/models.py @@ -38,12 +38,12 @@ def instantiate_object_id_field(object_id_class_or_tuple=models.TextField): @python_2_unicode_compatible class FieldHistory(models.Model): object_id = instantiate_object_id_field(getattr(settings, OBJECT_ID_TYPE_SETTING, models.TextField)) - content_type = models.ForeignKey('contenttypes.ContentType', db_index=True) + content_type = models.ForeignKey('contenttypes.ContentType', db_index=True, on_delete=models.CASCADE) object = GenericForeignKey() field_name = models.CharField(max_length=500, db_index=True) serialized_data = models.TextField() date_created = models.DateTimeField(auto_now_add=True, db_index=True) - user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True) + user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.CASCADE) objects = FieldHistoryManager() diff --git a/field_history/tracker.py b/field_history/tracker.py index b132a27..972788a 100644 --- a/field_history/tracker.py +++ b/field_history/tracker.py @@ -124,7 +124,7 @@ def get_field_history_user(self, instance): return instance._field_history_user except AttributeError: try: - if self.thread.request.user.is_authenticated(): + if self.thread.request.user.is_authenticated: return self.thread.request.user return None except AttributeError: diff --git a/runtests.py b/runtests.py index c8e3333..08d91cc 100644 --- a/runtests.py +++ b/runtests.py @@ -14,6 +14,7 @@ }, ROOT_URLCONF="tests.urls", INSTALLED_APPS=[ + "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", @@ -22,7 +23,7 @@ "tests", ], SITE_ID=1, - MIDDLEWARE_CLASSES=( + MIDDLEWARE=( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', diff --git a/tests/models.py b/tests/models.py index 490fa28..e81ed27 100644 --- a/tests/models.py +++ b/tests/models.py @@ -10,7 +10,7 @@ class Pet(models.Model): class Person(models.Model): name = models.CharField(max_length=255) - created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True) + created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.CASCADE) field_history = FieldHistoryTracker(['name']) @@ -20,7 +20,7 @@ def _field_history_user(self): class Owner(Person): - pet = models.ForeignKey(Pet, blank=True, null=True) + pet = models.ForeignKey(Pet, blank=True, null=True, on_delete=models.CASCADE) field_history = FieldHistoryTracker(['name', 'pet']) diff --git a/tests/tests.py b/tests/tests.py index 8b68b16..ddac147 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,10 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- import datetime +from decimal import Decimal from django.contrib.auth import get_user_model from django.core.management import CommandError, call_command -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from django.test.utils import override_settings from django.test import TestCase @@ -182,14 +183,14 @@ def test_field_history_works_with_integer_field(self): self.assertIsNotNone(history.date_created) def test_field_history_works_with_decimal_field(self): - human = Human.objects.create(body_temp=98.6) + human = Human.objects.create(body_temp=Decimal(98.6)) self.assertEqual(human.get_body_temp_history().count(), 1) history = human.get_body_temp_history()[0] self.assertEqual(history.object, human) self.assertEqual(history.field_name, 'body_temp') - self.assertEqual(history.field_value, 98.6) + self.assertEqual(history.field_value, Decimal(98.6)) self.assertIsNotNone(history.date_created) def test_field_history_works_with_boolean_field(self): diff --git a/tests/urls.py b/tests/urls.py index 45c4c60..a9201a4 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls import include, url +from django.conf.urls import url from django.contrib import admin from . import views @@ -6,5 +6,5 @@ urlpatterns = [ url(r"^$", views.test_view, name="index"), - url(r"^admin/", include(admin.site.urls)), + url(r"^admin/", admin.site.urls), ]