{"id":16624249,"url":"https://github.com/dcramer/objtrack","last_synced_at":"2025-07-05T08:36:11.878Z","repository":{"id":821600,"uuid":"534831","full_name":"dcramer/objtrack","owner":"dcramer","description":"Generic object 'viewed' status tracking in Django","archived":false,"fork":false,"pushed_at":"2010-05-17T20:08:12.000Z","size":116,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-21T13:49:36.113Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dcramer.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-02-24T23:48:10.000Z","updated_at":"2023-09-08T16:26:27.000Z","dependencies_parsed_at":"2022-07-05T17:03:09.153Z","dependency_job_id":null,"html_url":"https://github.com/dcramer/objtrack","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dcramer/objtrack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcramer%2Fobjtrack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcramer%2Fobjtrack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcramer%2Fobjtrack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcramer%2Fobjtrack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dcramer","download_url":"https://codeload.github.com/dcramer/objtrack/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcramer%2Fobjtrack/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261211684,"owners_count":23125543,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T03:45:40.187Z","updated_at":"2025-07-05T08:36:11.859Z","avatar_url":"https://github.com/dcramer.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"A generic object view tracking model.\n\nThis will store a \"last viewed date\" which says \"everything that has changed\" since this date, is unread. It also stores a list of primary keys, which has been read since that date.\n\nInstall\n-------\n\nDownload and install the package using distutils::\n\n\n\tpip install objtrack\n\nUpdate your settings.py and add the installed apps settings::\n\n\tINSTALLED_APPS = (\n\t    'django.contrib.admin',\n\t    'django.contrib.auth',\n\t    'django.contrib.contenttypes',\n\t    'django.contrib.sessions',\n\t    'objtrack',\n\t)\n\nFinally, run `python manage.py syncdb` to create the database tables.\n\nUsage\n-----\n\nShowing forums which have new posts in them::\n\n\tfrom objtrack.models import ObjectTracker\n\t\n\tdef view_forum_list(request):\n\t    categories = Category.objects.all()\n    \n\t    tracking = ObjectTracker.objects.get_for_request(request, Thread)\n    \n\t    # Don't forget you still need to update a date field when a new thread\n\t    # is added to the forum.\n\t    for category in categories:\n\t        category.has_new_posts = tracking.has_viewed(category)\n\n\t    # Maybe we want to mark all forums as \"i saw this\" now?\n\t    tracking.mark_all_as_viewed()\n\t    \n\t    return render(...)\n\n\nAdding a `has_viewed` attribute to threads in the thread listing::\n\n\tdef view_thread_list(request):\n\t    threads = Thread.objects.all()\n\t    \n\t    tracking = ObjectTracker.objects.get_for_request(request, Thread)\n\t    \n\t    # This isn't the *best* approach to checking if it's been viewed, but it works\n\t    for thread in threads:\n\t        thread.has_viewed = tracking.has_viewed(thread)\n\t    \n\t    return render(...)\n\n\nMarking the thread object as read when it's viewed::\n\n\tdef view_thread(request, thread_id):\n\t    thread = Thread.objects.get(pk=thread_id)\n\t    \n\t    tracking = ObjectTracker.objects.get_for_request(request, Thread)\n\t    tracking.mark_as_viewed(thread)\n\t    \n\t    return render(...)\n\nYou can also use it within Coffin or Django templates::\n\n\t{% load tracking %}\n\t\n\t{% for instance, has_viewed in queryset|with_tracking(request.session, \"date_field\") %}\n\t\t...\n\t{% endfor %}","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcramer%2Fobjtrack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdcramer%2Fobjtrack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcramer%2Fobjtrack/lists"}