oli@dev0 ~ % cat projects/django-reviews.md

Django Reviews

Django Reviews adds customer reviews to a Django website, with approval before publication and owner replies managed in the admin.

Customer reviews page with an overall rating, rating breakdown, and approved reviews.

Django Reviews gives customers a place to share their experience and business owners a clear way to manage what appears on their website. Visitors can read approved reviews, filter by rating, and submit their own feedback. The public interface includes Dutch, French, and English translations.

From submission to publication

New reviews wait for approval in Django admin, where the owner can also publish a reply. The original submission stays unchanged during moderation. Public pages receive only the fields they need, keeping private details such as the customer's car description out of the review listing.

Protecting the submission form

The form uses a few checks to help keep spam out. A hidden field, called a honeypot, catches bots that fill it in. IP-based limits slow repeated attempts, while a keyed hash lets the app count them without saving the raw IP address in review records.

Django’s CSRF protection helps block unwanted submissions from other websites. Signed, time-limited tokens help detect altered or expired forms. If a submission arrives unusually quickly or its token isn’t valid, the visitor gets a short verification question.

Handling the less visible details

The app saves each accepted review before attempting the notification email. Repeated requests from the same signed submission don't create duplicate reviews, and uncertain email delivery is left for the owner to check and retry. Focused tests cover these cases alongside moderation, privacy, and translated pages.

The pages use Django templates with small JavaScript enhancements. The repository provides the review app, tests, and integration examples for adapting it to an existing Django project.

Project information

Category
Features

Built with

  • Python
  • Django
  • HTML5
  • CSS3
  • JavaScript
View full feature list

Django Reviews lets customers leave feedback on a Django website. The business owner checks each review before it appears, can reply to it, and manages everything through Django admin.

Reading reviews

  • See approved reviews with a star rating, review text, date, and the customer's chosen name. Customers who leave the name blank appear as Anonymous.
  • Read the newest reviews first, with 30 reviews on each page.
  • Filter by star rating to find the feedback you're interested in.
  • See the average rating, total number of reviews, and how many reviews received each score. These figures always cover all approved reviews.
  • Read the owner's reply below a review.
  • Open a direct link to a particular review, even if it has moved to another page as new reviews arrive. If it's no longer available, the page explains that.
  • Show the latest 10 approved reviews in a scrolling section on the homepage, with links to read longer comments.

Leaving a review

  • Choose a rating from one to five stars. No score is selected in advance.
  • Add an optional public name of up to 30 characters.
  • Describe the car that was cleaned using up to 30 characters. This required detail stays private and helps the owner check the customer's experience.
  • Write a review of up to 255 characters.
  • See character counts as you type and clear messages if something needs fixing.
  • Keep your entered text when the form returns with a validation error or an extra security check.
  • See when your review is being sent and receive a confirmation page once it's accepted.
  • Get guidance on retrying if the browser can't confirm whether the review arrived.
  • Read what will become public before submitting, with a link to the privacy policy.
  • Receive a warning before changing language if that would discard your unfinished review.

Keeping spam under control

The form uses several checks together. Each handles a different kind of unwanted submission.

  • Hidden honeypot: a field that ordinary visitors don't need to fill in. If an automated bot fills it in, the submission is rejected.
  • IP-based limits: restrict how many attempts and accepted reviews can come from the same IP address within a set period. An IP address identifies a network connection, so people on a shared network can share these limits.
  • Hashed IP storage: the app turns the IP address into a protected identifier for counting attempts. It stores that identifier instead of the raw address in its review protection records. The website's own access logs are managed separately.
  • Trusted address checks: the website supplies rules for finding the visitor's IP address when traffic passes through a proxy or hosting service.
  • Signed form tokens: each form includes a time-limited digital stamp that lets the app check whether its supporting information has been changed.
  • Extra verification: a form submitted unusually quickly, or with a missing, invalid, or expired stamp, asks the visitor to solve a short arithmetic question. The answer check belongs to that submission and also expires.
  • CSRF protection: Django checks for attempts by another website to make a visitor's browser submit the form without their intention.
  • Checks on the server: required fields, ratings, and text limits are checked again when the form arrives. Changing the form in a browser doesn't bypass those rules.
  • Protection during busy periods: limits still apply when several requests arrive together. If the app can't complete its protection checks, it asks the visitor to try later.

Avoiding lost or duplicate reviews

  • Retrying the same accepted submission doesn't create another review, including when the browser missed the confirmation.
  • A genuinely new form submission counts separately, even if its text matches an earlier review.
  • The review is saved before the app tries to email the owner. An email problem doesn't erase the customer's feedback.
  • The app keeps a record of accepted submissions so eligible retries don't immediately bring back a deleted review.
  • The customer's original words, rating, and submission details stay unchanged during moderation.
  • Stored data has rules that reject invalid ratings and review statuses.
  • Old spam-limit records and eligible records of deleted submissions are cleaned up when they expire.

Managing reviews as the owner

  • Use Django admin, the website's management area, with access restricted to the verified owner.
  • Check new reviews before approving them for the public website.
  • Reject a review, return it for reconsideration, or remove an approved review from public view.
  • Filter the admin list by rating, review status, or email delivery status.
  • Read the original submission without rewriting the customer's feedback. Creating reviews manually through admin is disabled too.
  • Write and edit an owner reply of up to 1,000 characters, with a character counter.
  • Prepare a reply before approving the review. It becomes public when the review is approved.
  • Keep track of when a reply was first published and later edited.
  • Remove a reply through a separate action.
  • Confirm before deleting a review. Deletion also removes its linked notification email, and the standard bulk-delete action is disabled.
  • Resolve an unfinished email send before deleting the affected review, so the two actions don't interfere.

Getting email notifications

  • Notify the owner when a new review has been accepted.
  • Keep an email record and show its delivery status in admin.
  • Coordinate sending attempts so two requests don't independently send the same notification at once.
  • Let the owner retry a failed notification after checking its latest status.
  • Flag uncertain delivery for the owner to check instead of automatically sending another email.
  • Avoid sending a fresh submission notification just because someone edits a reply, moderates a review, or retries an already accepted form.

Privacy and languages

  • Publish only the review details visitors need. Car information, spam checks, moderation details, and email status stay private.
  • Save the publication notice associated with the submission, including its wording, language, version, and links.
  • Offer the public interface in Dutch, French, and English.
  • Keep customer reviews and owner replies in the language they were written in. They aren't automatically translated.
  • Keep owner-facing moderation and notification messages in Dutch.
  • Tell browsers and caches not to store form, confirmation, and direct-review lookup responses.
  • Ask search engines to leave forms, confirmation pages, filtered listings, empty listings, and review-lookup URLs out of search results.
  • Limit the address information sent when following links from form, confirmation, and review-lookup pages to other websites.

Making the pages easier to use

  • Label form fields clearly and connect them to their help text and error messages.
  • Let visitors choose ratings with standard keyboard controls, with text descriptions for the stars.
  • Provide error and progress messages that assistive technology can announce.
  • Help visitors move to fields that need attention and to messages about unavailable reviews.
  • Support dragging and scrolling through homepage reviews.
  • Turn off automatic carousel movement when the visitor requests reduced motion. Movement also stops while the browser tab is hidden and pauses around interaction.
  • Use ordinary Django pages with small JavaScript additions for counters, form feedback, and scrolling reviews.

Adapting it to another website

  • Includes the review app, page templates, styling, translations, and database setup files.
  • Provides an example page layout that you can adapt to the website's design.
  • Includes examples and documentation for connecting the app to an existing Django project.
  • Lets the developer adjust submission limits, security-check timings, trusted proxies, and notification addresses.
  • Includes automated tests for submissions, spam protection, duplicate prevention, moderation, replies, privacy, translations, and email recovery.
  • Includes tests for requests arriving at the same time, plus checks for character counting and carousel behaviour.
  • Shares the code under the MIT license.

Full feature list