{ "info": { "author": "Eric Florenzano", "author_email": "floguy@gmail.com", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Framework :: Django", "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Overview of django-classfaves\n-----------------------------\n\nThis app provides everything that you need to add favoriting abilities to\nyour site! There are just a few steps that you need to go through to add\nthis functionality to your site.\n\n\nInstallation at a Glance\n========================\n\n1. Create a favorite model that has a ``ForeignKey`` to the domain object\n that you would like to be able to favorite or unfavorite.\n\n2. Instantiate ``CreateFavorite``, ``DeleteFavorite``, and ``UserFavorites``\n in one of your url configurations, and map them into your urlpatterns.\n\n3. Integrate into your domain object's templates and views.\n\n\nInstallation Example: Arcade Site\n=================================\n\nThis installation example comes from `Radiosox`_, for which this application\nwas originally written. The site is a free online arcade site that allows\nusers to mark certain games as their favorite ones. They are allowed to\nun-favorite those games if they change their mind. Finally, they are allowed\nto see a list of their favorite games.\n\nStep 1: Creating our Model\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWe already have a domain object that looks a little bit like this:\n\n.. sourcecode:: python\n\n from django.db import models\n\n class Game(models.Model):\n name = models.CharField(max_length=64)\n slug = models.SlugField(max_length=64)\n description = models.TextField(blank=True)\n # ... there are many more fields here\n\nNow what we want to do is in that same models.py file, we will create our\nfavorite model, like shown here:\n\n.. sourcecode:: python\n\n from classfaves.models import FavoriteBase\n\n class GameFavorite(FavoriteBase):\n game = models.ForeignKey(Game)\n\nWhat this does is use our ``FavoriteBase`` abstract base class, provide by\ndjango-classfaves, and ensure that it's got a link to our ``Game`` domain\nobject. This model is equivalent to manually writing this:\n\n.. sourcecode:: python\n\n import datetime\n \n from django.db import models\n from django.contrib.auth.models import User\n\n class GameFavorite(models.Model):\n game = models.ForeignKey(Game)\n user = models.ForeignKey(User)\n date_created = models.DateTimeField(default=datetime.datetime.now)\n\nIn fact, you could write that model if you prefer. I prefer to subclass\n``FavoriteBase``, since it's easier.\n\n\nStep 2: Attaching our Views\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn our ``urls.py`` file for that arcade app whose models we were using in the\nprevious step, we have something that, right now, looks like this:\n\n.. sourcecode:: python\n\n from django.conf.urls.defaults import patterns, url\n\n urlpatterns = patterns('arcade.views',\n url(r'^popular/$', 'popular', name='arcade_popular'),\n url(r'^new/$', 'new', name='arcade_new'),\n # ... there are more URLs here\n )\n\nWhat we want to do first is instantiate our views provided by the\ndjango-classfaves app:\n\n.. sourcecode:: python\n\n from arcade.models import GameFavorite, Game\n from classfaves.views import CreateFavorite, DeleteFavorite, UserFavorites\n\n create_favorite = CreateFavorite(GameFavorite, Game)\n delete_favorite = DeleteFavorite(GameFavorite, Game)\n public_games = lambda qs: qs.filter(game__enabled=True)\n user_favorites = UserFavorites(GameFavorite, Game, extra_filter=public_games)\n\nWhat this does is give us views to create, delete, and get user favorites for\nall games in the system. You'll note that we're passing an argument named\n``extra_filter`` to ``UserFavorites`` which limits the view to only showing\ngames with ``enabled`` set to ``True``. This can be used to limit the\n``QuerySet`` arbitrarily. Kinda cool, huh?\n\nAnyway, the next step is to modify our ``urlpatterns`` so that it maps to these\nviews:\n\n..sourcecode:: python\n\n urlpatterns = patterns('arcade.views',\n url(r'^popular/$', 'popular', name='arcade_popular'),\n url(r'^new/$', 'new', name='arcade_new'),\n # ... vvv THE NEW URLS ARE BELOW vvv\n url(r'^favorites/create/(?P\\d+)/$', create_favorite, name='arcade_favorite_create'),\n url(r'^favorites/delete/(?P\\d+)/$', delete_favorite, name='arcade_favorite_delete'),\n url(r'^favorites/list/$', user_favorites, name='arcade_my_favorites'),\n url(r'^favorites/list/(?P[a-zA-Z0-9_-]+)/$', user_favorites, name='arcade_user_favorites'),\n )\n\nNote how we were able to give the new views proper URL names, and how we were\nable to easily place them where they logically fit in the URL structure--under\nthe URL space of the arcade app. Also note that we've ensured to have a ``pk``\nfor the create and delete views.\n\n\nStep 3: Integration\n~~~~~~~~~~~~~~~~~~~\n\nAdmittedly, this part is the part where django-classfaves helps you out the\nleast. Well, basically, django-classfaves doesn't help you out at all. The\nreason for this is by design: we don't know how your app is structured or how\nyou want to use it, so we want to leave this bit completely up to you.\n\nSo here's how we did it. First, on the page where you actually play the game,\nwe want you to be able to decide that you like it and favorite it. We also\nwanted to make sure that you could do this while you are still playing the\ngame, so it needed to be asynchronous using JavaScript.\n\nOur first step was to modify the view function for the game playing page.\n\n..sourcecode:: python\n\n from arcade.models import GameFavorite\n\n def play(request, game_slug=None):\n # ... some of our view code here\n favorite = False\n if request.user.is_authenticated():\n favorite = GameFavorite.objects.filter(user=request.user,\n game=game).count() > 0\n context = {\n # ... other context here\n 'favorite': favorite,\n }\n # ... the rest of our view code here\n\nJust a few lines of code, and we now know whether the user has a favorite on\nthat specific domain object (the game) or not.\n\nNow, in the template, we do this with the information:\n\n..sourcecode:: python\n\n {% if user.is_authenticated %}\n {% if favorite %}\n Remove as Favorite\n {% else %}\n Add as Favorite\n {% endif %}\n {% else %}\n Add as Favorite\n {% endif %}\n\nIn other words, based on whether the user is authenticated and based on whether\nor not they have already favorited the game, we set some classes and urls and\nmessages on the links.\n\nWe also have a bit of JavaScript, that looks like this:\n\n..sourcecode:: javascript\n\n var add_favorite_handlers = function(base_create, base_delete) {\n $('a.favorite.fave').live('click', function(e) {\n var pk = $(this).attr('id').replace('favorite_', '');\n var url = base_create + pk + '/';\n $.getJSON(url, function(data, textStatus) {\n $('#favorite_' + pk).removeClass('fave').addClass('unfave').text('Remove as Favorite');\n });\n return false;\n });\n $('a.favorite.unfave').live('click', function(e) {\n var pk = $(this).attr('id').replace('favorite_', '');\n var url = base_delete + pk + '/';\n $.getJSON(url, function(data, textStatus) {\n $('#favorite_' + pk).removeClass('unfave').addClass('fave').text('Add as Favorite');\n });\n return false;\n });\n };\n\nI'm not going to go into too much detail about this JavaScript code, except to\nsay that it takes the base URL for the create and the delete pages, and turns\nlinks with certain classes into AJAX calls into the create and delete views.\n\nFinally, at the bottom of the page, we initialize this JavaScript like so:\n\n.. sourcecode:: html\n\n \n\nAnd with that, we're done! Not too bad, huh? You can browse around `Radisox`\nand play a game to see it in action. Look up at the top right of any game\npage to see the favorite/un-favorite button.\n\n.. _`Radiosox`: http://radiosox.com/", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/ericflo/django-classfaves", "keywords": "favorites,faves,django,class-based", "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "django-classfaves", "package_url": "https://pypi.org/project/django-classfaves/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-classfaves/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/ericflo/django-classfaves" }, "release_url": "https://pypi.org/project/django-classfaves/0.1/", "requires_dist": null, "requires_python": null, "summary": "A different approach to favorites in Django", "version": "0.1" }, "last_serial": 122991, "releases": { "0.1": [] }, "urls": [] }