1===================
2django-star-ratings
3===================
4
5|Build Status| |codecov.io| |Documentation Status|
6
7Python 3 compatible ratings for Django.
8
9Add ratings to any Django model with a template tag.
10
11See full `documentation
12<http://django-star-ratings.readthedocs.io/en/latest/?badge=latest/>`_.
13
14Requirements
15============
16
17* Python 3.6+.
18* Django 2.0+
19
20
21Installation
22============
23
24Install from PyPI:
25
26::
27
28    pip install django-star-ratings
29
30add ``star_ratings`` to ``INSTALLED_APPS``:
31
32::
33
34    INSTALLED_APPS = (
35        ...
36        'star_ratings'
37    )
38
39sync your database:
40
41::
42
43    python manage.py migrate
44
45add the following to your urls.py:
46
47::
48
49    url(r'^ratings/', include('star_ratings.urls', namespace='ratings', app_name='ratings')),
50
51Make sure ``'django.core.context_processors.request',`` is in
52``TEMPLATE_CONTEXT_PROCESSORS``.
53
54Usage
55=====
56
57Add the following javascript and stylesheet to your template
58
59::
60
61    {% load static %}
62    <html>
63    ...
64    <link rel="stylesheet" href="{% static 'star-ratings/css/star-ratings.css' %}">
65    <script type="text/javascript" src="{% static 'star-ratings/js/dist/star-ratings.min.js' %}"></script>
66    ...
67    </html>
68
69To enable ratings for a model add the following tag in your template
70
71::
72
73    {% load ratings %}
74    <html>
75    ...
76    {% ratings object %}
77    ...
78    </html>
79
80Template tags
81=============
82
83The template tag takes four arguments:
84
85-  ``icon_height``: defaults to ``STAR_RATINGS_STAR_HEIGHT``
86-  ``icon_width``: defaults to ``STAR_RATINGS_STAR_WIDTH``
87-  ``read_only``: overrides the ``editable`` behaviour to make the widget read only
88-  ``template_name``: overrides the tempalte to use for the widget
89
90Settings
91========
92
93To prohibit users from altering their ratings set
94``STAR_RATINGS_RERATE = False`` in settings.py
95
96To change the number of rating stars, set ``STAR_RATINGS_RANGE``
97(defaults to 5)
98
99To enable anonymous rating set ``STAR_RATINGS_ANONYMOUS = True``.
100
101Anonymous Rating
102================
103
104If anonymous rating is enabled only the ip address for the rater will be stored (even if the user is logged in).
105When a user rates an object a preexisting object will not be searched for, instead a new rating object will be created
106
107**If this value is changed your lookups will return different results!**
108
109To control the default size of stars in pixels set the values of ``STAR_RATINGS_STAR_HEIGHT`` and
110``STAR_RATINGS_STAR_WIDTH``. By default ``STAR_RATINGS_STAR_WIDTH`` is the same as
111``STAR_RATINGS_STAR_HEIGHT`` and ``STAR_RATINGS_STAR_HEIGHT`` defaults to 32.
112
113
114Changing the star graphics
115==========================
116
117To change the star graphic, add a sprite sheet to
118``/static/star-ratings/images/stars.png`` with the states aligned
119horizontally. The stars should be laid out in three states: full, empty
120and active.
121
122You can also set ``STAR_RATINGS_STAR_SPRITE`` to the location of your sprite sheet.
123
124Customize widget template
125=========================
126
127You can customize ratings widget by creating ``star_ratings/widget.html``. For example :
128
129::
130
131    {% extends "star_ratings/widget_base.html" %}
132    {% block rating_detail %}
133    Whatever you want
134    {% endblock %}
135
136See ``star_ratings/widget_base.html`` for other blocks to be extended.
137
138Ordering by ratings
139===================
140
141The easiest way to order by ratings is to add a ``GenericRelation`` to
142the ``Rating`` model from your model:
143
144::
145
146    from django.contrib.contenttypes.fields import GenericRelation
147    from star_ratings.models import Rating
148
149    class Foo(models.Model):
150        bar = models.CharField(max_length=100)
151        ratings = GenericRelation(Rating, related_query_name='foos')
152
153    Foo.objects.filter(ratings__isnull=False).order_by('ratings__average')
154
155Custom Rating Model
156===================
157
158In some cases you may need to create your own rating model. This is possible
159by setting ``STAR_RATING_RATING_MODEL`` in your settings file. This can be useful
160to add additional fields or methods to the model. This is very similar to the how
161django handles swapping the user model
162(see [https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#substituting-a-custom-user-model]).
163
164For ease ``AbstractBaseRating`` is supplied. For example if you wanted to add the
165field ``foo`` to the rating model you would need to crate your rating model
166extending ``AbstractBaseRating``:
167
168::
169
170   ./myapp/models.py
171
172   class MyRating(AbstractBaseRating):
173      foo = models.TextField()
174
175And add the setting to the setting file:
176
177::
178
179   ./settings.py
180
181   ...
182   STAR_RATINGS_RATING_MODEL = 'myapp.MyRating'
183   ...
184
185**NOTE:** If you are using a custom rating model there is an issue with how django
186migration handles dependency orders. In order to create your initial migration you
187will need to comment out the ``STAR_RATINGS_RATING_MODEL`` setting and run
188``makemigrations``. After this initial migration you will be able to add the setting
189back in and run ``migrate`` and ``makemigrations`` without issue.
190
191Changing the ``pk`` type (Requires django >= 1.10)
192==================================================
193
194One use case for changing the rating model would be to change the pk type of the
195related object. By default we assume the pk of the rated object will be a
196positive integer field which is fine for most uses, if this isn't though you will
197need to override the ``object_id`` field on the rating model as well as set
198STAR_RATINGS_OBJECT_ID_PATTERN to a reasonable value for your new pk field. As
199of django 1.10 you can now hide fields form parent abstract models, so to change
200the ``object_id``to a ``CharField`` you can do something like:
201
202::
203
204   class MyRating(AbstractBaseRating):
205      object_id = models.CharField(max_length=10)
206
207And add the setting to the setting file:
208
209::
210
211   ./settings.py
212
213   ...
214   STAR_RATINGS_OBJECT_ID_PATTERN = '[a-z0-9]{32}'
215   ...
216
217
218Events
219======
220
221Some events are dispatched from the javascript when an object is raised. Each
222event that ias dispatched has a ``details`` property that contains information
223about the object and the rating.
224
225``rate-success``
226----------------
227
228Dispatched after the user has rated an object and the display has been updated.
229
230The event details contains
231
232::
233
234    {
235        sender: ... // The star DOM object that was clicked
236        rating: {
237            average: ... // Float giving the updated average of the rating
238            count: ... // Integer giving the total number of ratings
239            percentage: ... // Float giving the percentage rating
240            total: ... // Integer giving the sum of all ratings
241            user_rating: ... // Integer giving the rating by the user
242    }
243
244``rate-failed``
245---------------
246
247Dispatched after the user has rated an object but the server responds with an error.
248
249The event details contains
250
251::
252
253    {
254        sender: ... // The star DOM object that was clicked
255        error: ... // String giving the error message from the server
256    }
257
258
259Running tests
260-------------
261
262To run the test use:
263
264::
265
266    $> ./runtests.py
267
268.. |Build Status| image:: https://travis-ci.org/wildfish/django-star-ratings.svg?branch=master
269   :target: https://travis-ci.org/wildfish/django-star-ratings
270.. |codecov.io| image:: http://codecov.io/github/wildfish/django-star-ratings/coverage.svg?branch=master
271   :target: http://codecov.io/github/wildfish/django-star-ratings?branch=master
272.. |Documentation Status| image:: https://readthedocs.org/projects/django-star-ratings/badge/?version=latest
273   :target: http://django-star-ratings.readthedocs.io/en/latest/?badge=latest
274   :alt: Documentation Status
275
276
277Releasing
278---------
279
280Travis is setup to push releases to pypi automatically on tags, to do a release:
281
2821. Up version number.
2832. Update release notes.
2843. Push dev.
2854. Merge develop into master.
2865. Tag with new version number.
2876. Push tags.
288