diff --git a/README.rst b/README.rst
index 3d4a855..0502160 100644
--- a/README.rst
+++ b/README.rst
@@ -83,6 +83,16 @@ customize the extracted links:
``image_fields``: a list of ``ImageField`` field names whose content will be
considered as links. Empty ``ImageField`` content is always ignored.
+ ``filter_callable``: a callable which allows allows to pass a function as filter
+ for your linklist class. It allows to apply more advanced filter operations.
+ This function must be a class method and it should be passed the objects query
+ set and return the filtered objects.
+ Example usage in your linklists.py - only check latest versions:
+ @classmethod
+ def filter_callable(cls, objects):
+ latest = Model.objects.filter(id=OuterRef('id')).order_by('-version')
+ return objects.filter(version=Subquery(latest.values('version')[:1]))
+
Management commands
-------------------
diff --git a/linkcheck/__init__.py b/linkcheck/__init__.py
index 10b5672..d85f4f9 100644
--- a/linkcheck/__init__.py
+++ b/linkcheck/__init__.py
@@ -121,17 +121,6 @@ class Linklist:
object_filter = None
object_exclude = None
-
- # filter_callable allows to pass a function as filter for your linklist class.
- # It allows to apply more advanced filter operations.
- # This function must be a class method and it should be passed the objects query set
- # and return the filtered objects.
- # Example usage in your linklists.py - only check latest versions:
- # @classmethod
- # def filter_callable(cls, objects):
- # latest = Model.objects.filter(id=OuterRef('id')).order_by('-version')
- # return objects.filter(version=Subquery(latest.values('version')[:1]))
-
filter_callable = None
def __get(self, name, obj, default=None):
diff --git a/linkcheck/tests/sampleapp/linklists.py b/linkcheck/tests/sampleapp/linklists.py
index 346bb65..f75effd 100644
--- a/linkcheck/tests/sampleapp/linklists.py
+++ b/linkcheck/tests/sampleapp/linklists.py
@@ -1,5 +1,6 @@
+from django.db.models import Subquery, OuterRef
from linkcheck import Linklist
-from linkcheck.tests.sampleapp.models import Author, Book
+from linkcheck.tests.sampleapp.models import Author, Book, Journal
class BookLinklist(Linklist):
@@ -16,7 +17,18 @@ class AuthorLinklist(Linklist):
url_fields = ['website']
+class JournalLinklist(Linklist):
+ """ Class to let linkcheck app discover fields containing links """
+ model = Journal
+ html_fields = ['description']
+ @classmethod
+ def filter_callable(cls, objects):
+ latest = Journal.objects.filter(title=OuterRef('title')).order_by('-version')
+ return objects.filter(version=Subquery(latest.values('version')[:1]))
+
+
linklists = {
'Books': BookLinklist,
'Authors': AuthorLinklist,
+ 'Journals': JournalLinklist,
}
diff --git a/linkcheck/tests/sampleapp/models.py b/linkcheck/tests/sampleapp/models.py
index c40034f..af87065 100644
--- a/linkcheck/tests/sampleapp/models.py
+++ b/linkcheck/tests/sampleapp/models.py
@@ -13,3 +13,9 @@ class Author(models.Model):
# This model has purposefully no get_absolute_url
name = models.CharField(max_length=50)
website = models.URLField(blank=True)
+
+
+class Journal(models.Model):
+ title = models.CharField(max_length=50)
+ description = models.TextField()
+ version = models.PositiveIntegerField(default=0)
diff --git a/linkcheck/tests/test_linkcheck.py b/linkcheck/tests/test_linkcheck.py
index 14784a3..aa4332b 100644
--- a/linkcheck/tests/test_linkcheck.py
+++ b/linkcheck/tests/test_linkcheck.py
@@ -21,7 +21,7 @@
from linkcheck.models import Link, Url
from linkcheck.views import get_jquery_min_js
-from .sampleapp.models import Author, Book
+from .sampleapp.models import Author, Book, Journal
#MOCK addinfurl
@@ -425,3 +425,24 @@ class FixtureTestCase(TestCase):
def test_fixture(self):
self.assertEqual(Book.objects.count(), 1)
+
+
+class FilterCallableTestCase(TestCase):
+ def test_filter_callable(self):
+ all_linklists = apps.get_app_config('linkcheck').all_linklists
+ all_linklists['Journals'].html_fields = []
+ Journal.objects.create(title='My Title', description="""
+ My description Example""")
+ Journal.objects.create(title='My Title', version=1, description="""
+ My new description Example""")
+ all_linklists['Journals'].html_fields = ['description']
+ # assert there are two versions of the same journal
+ self.assertEqual(Journal.objects.count(), 2)
+ # assert command just finds the latest version of same journals
+ out = StringIO()
+ call_command('findlinks', stdout=out)
+ self.assertEqual(
+ out.getvalue(),
+ "Finding all new links...\n"
+ "1 new Url object(s), 1 new Link object(s), 0 Url object(s) deleted\n"
+ )