Best Practices: How to best implement Rating-Stars in Django Templates [closed] - django

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I would like to have reusable ratings (typical layout with 5 stars).
I have found this http://www.thebroth.com/blog/119/css-rating-stars that explains how to display this using css.
For actually collecting the rating I was thinking of using an image map or maybe simple radio buttons.
I would like to use this on various different models.
How would you do this?
Shall I create a widget or can I do this with a template?
Actually I was pretty surprised not to find anything on this on the web. Is it that simple, or uncommon?

If received some interesting answers on the django-users mailing list:
by Mike:
Well you can create a widget, I like a seperate rating model myself. That
collects the value and then adds that to a total and creates a score or
average. The model stores the total votes and the total score, which I divide
and get my average, (I do the math in the view). Adding it to other models
with a foreign key relation. Enforcing that users vote only once is rarely
enforced outside of the current session or cookie lifetime. If you want it
persistance, I'm notfgv6gw33TT sure off the top of my head what is best for
this, but would require only registered users vote.
Now, you just display the rating form, I would do it as a template inclusion
tag and put the tag in my templates. This tag has the basic submit form, the
form it's self is two fields, with a select box (I went simple this way) and a
hidden field labeled next that points back to this page, that I can redirect
to. When the user submits, in my views to handle the forms action, I just
increment the votes and total score and redirect back to the page the vote was
taken on. This is using the traditional submit button, posting the form to a
url, returning a full view.
If you do something with javascript that illuminates the number of stars for
the rating and click on the stars to submit, here you might want to post it as
json object using xhr request, update the view and return a json object with
the updated rating values, if it's a 200, update the page with the new values
after voting (returned with the 200). If it's a 500, deal with the error,
letting the user know, there was a problem voting and reset the stars.
This is what I do, or would do in your position, if anyone has a better idea,
please speak up.
Hope this helps.
Mike
by Ethan:
I actually just did 5-star ratings for a project I'm working on, and have
been trying to figure out if I have anything reusable worth releasing as a
package (and trying to find the time to figure that out..) I'll outline
what I did and what I used to do it.
I used django-ratings[1,2] for the backend and hooked up its RatingField to
my rateable models.
I like jQuery, so for the frontend I used the jquery-star-rating plugin[3,4]
as a base. It turns a collection of radio buttons into a star widget. I
haven't looked closely at the implementation but I think it's basically
using the same CSS technique described in your link. To get started you
just need to include its JS and CSS and add class="star" to the radio
buttons in your form.
I then just wrote some view code that sends the request data from the radio
buttons to django-ratings. Super simple stuff, just used the django-ratings
RatingManager API and handled the exceptions it throws -- I've pasted the
snippet from my code at [5]. (I'm using a somewhat old version of
django-ratings b/c I haven't had the time to upgrade; it might look a little
different now, I'm not sure.)
Finally, I wanted two more things:
1) If a user has already rated an item and views the "rate this item" form
again, the "star widget" should be preset with the user's previous rating,
instead of just showing five blank stars. I realized the easiest way to do
this was from the client side: an onload event that simulates the user
clicking on the star he already clicked on. My view and template code for
that is at [6]; I just figured out the HTML formats that jquery-star-rating
sets and expects, and clicked on the appropriate star for the user's
existing rating.
2) When viewing the item, users' ratings should show up as non-interactive
stars, instead of as numbers. I wrote a dumb-as-nails template filter
designed to take a number (the rating) and return a bunch of star images.
Again, I just used the HTML formatting and CSS classes from
jquery-star-rating. My code for this is at [7].
I was thinking it'd be neat to put some of this in a django-form Field that
renders the radio buttons and triggers jquery-star-rating all in one go, and
handles the submission to the django-ratings backend. But I haven't had a
chance to figure that out yet.
Anyway, hope this helps,
Ethan
1 http://github.com/dcramer/django-ratings
[2] http://pypi.python.org/pypi/django-ratings
[3] http://www.fyneworks.com/jquery/star-rating/
[4] http://code.google.com/p/jquery-star-rating-plugin/
[5] http://pastebin.ca/1650596
[6] http://pastebin.ca/1650609
[7] http://pastebin.ca/1650616

There is a django-ratings app on PyPi. It can give you the rating as a percent 'myinstance.rating.get_percent()' to use in your template for the inner div width in the CSS trick you mentioned.

Related

Is it possible to make 'cart' with django Class Based View?

I am trying to make a simple e-commerce website and followed some tutorials.
However, the author of the book used complicated function based view to make cart function..
there are bunch of session stuffs.. and I don't understand the logic..
and I am trying to think the other way..
what about using database to store all the cart related data, and
use CBV to build it?
for example,
CartListView to see the contents of the cart, and CartUpdateView to change the quantity..
then are they going to be two different pages? separated page that user should go to the
different page to change the value??
please help me T T
You can access the session in any sort of CBV as self.request.session and a "shopping cart" is normally stored therein.
You'll certainly need to implement a CartListView to see what's in it, or possibly a CartEditView to show the cart with options to edit the quantities and delete anything that shouldn't be in there.
Adding products to the cart may well be an "Add" button on a ProductDetailView or lots of add buttons in a ProductListView. You might add a POST handler method to these views which are otherwise read-only (GET-only) bt default. Or you might make them FormViews, even though the form would be hidden and filled/POSTed by JS rather than the shopper doing anything other than clicking "add".
And then there will be a CheckoutView.
Check https://djangopackages.org/ (put "cart" in the search box). this will throw up several shopping cart things which might be the code you want, or the source of which might be a valuable learning resource before you end up rolling your own.

Django save before leaving page prompt [duplicate]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I am currently building a registration page where if the user leaves, I want to pop up a CSS box asking him if he is sure or not. I can accomplish this feat using confirm boxes, but the client says that they are too ugly. I've tried using unload and beforeunload, but both cannot stop the page from being redirected. Using those to events, I return false, so maybe there's a way to cancel other than returning false?
Another solution that I've had was redirecting them to another page that has my popup, but the problem with that is that if they do want to leave the page, and it wasn't a mistake, they lose the page they were originally trying to go to. If I was a user, that would irritate me.
The last solution was real popup window. The only thing I don't like about that is that the main winow will have their destination page while the pop will have my page. In my opinion it looks disjoint. On top of that, I'd be worried about popup blockers.
Just to add to everyones comments. I understand that it is irritating to prevent users from exiting the page, and in my opinion it should not be done. Right now I am using a confirm box at this point. What happens is that it's not actually "preventing" the user from leaving, what the client actually wants to do is make a suggestion if the user is having doubts about registering. If the user is halfway through the registraiton process and leaves for some reason, the client wants to offer the user a free coupon to a seminar (this client is selling seminars) to hopefully persuade the user to register. The client is under the impression that since the user is already on the form, he is thinking of registering, and therefore maybe a seminar of what he is registering for would be the final push to get the user to register. Ideally I don't have to prevent the user from leaving, what would be just as good, and in my opinion better is if I can pause the unload process. Maybe a sleep command? I don't really have to keep the user on the page because either way they will be leaving to go to a different page.
Also, as people have stated, this is a terriable title, so if someone knows a better one, I'd really appreciate it if they could change the title to something no so spammer inviting.
As soon as I saw the words "prevent the user" I started to wail in agony. Never prevent the user, only help them.
If they see your registration page and run off, that's their choice. Pop up a javascript confirm box if they've already filled in some data (because they might be navigating away accidentally) but leave it at that. If they haven't touched the form, leave them alone - they don't want to fill in your form.
Look at other methods of engaging users. If your form is huge and scary, break it into simple manageable chunks or better yet, simplify things so much that the user only gives you data when you need it. For example, you might not need their address until you want to post something to them.
By breaking it into multiple parts you can hook them with a simple form and once they've invested that time, they'll be more likely to continue the process.
But don't harass users. If they don't want to register, pestering them with pop-ups and jaavscript dialogues will just chase them off the site completely.
With that in mind, assuming you're just trying to stop people half-filling-in forms, there are a couple of options to genuinely help people:
Detect if the form has changed and ask them a simple confirm() message.
This is all you can do. A CSS "pop-in" just won't work because you can't control* the window location in the unload event.
*You can put an event listener on all your page's links to fire off something to check the form, but this only helps if the user clicks on one of those links. It won't help if, for example, the user clicks back or closes the window. You could do both CSS and javascript but you end up with a bit of a mess.
Persist the state of the form behind the scenes.
An extension to #1. Instead of squabbling with the user, let them go where they want but save the content of the form either to session or cookie (if it'll fit) and put something on the page (like SO's orange prompt bars at the top of the page) that reminds them that they've started filling in a form and gives them a link back to the form.
When they click that link, you load the data out of the cookie (or session) back into the form and let them carry on. This has the clear benefit of letting them do what they like on your site and keeps the data safe.. ish.
If they don't come back and their cookie/session expire, that's their fault. You can only lead a horse to water. It's not your job to force it to drink.
Don't do it.
But if you want, try this. Record mouse positions and detect a quick upward thrust -- the user is reaching for the BIG X or the top left or top right. Now might be your chance for an unobtrusive box in the screen.
I've seen this implement on the web and it is evil.
If you want to trap links, you could rewrite the links in the page to go to a "you really want to leave?" javascript function, passing the destination URL as an argument.
If you wanna keep users from using their "Back" button, or keep them from putting another URL in the address bar, stop. Stop now. (1) Browsers were made to prevent exactly that kind of obnoxious behavior, and (2) Even if they allowed it, see the last two words of (1). It's freaking rude. Your site is not that special, no matter how cool you think it is.
window.onbeforeunload = function() { return "Message"; };
Use a JavaScript like this to display a leave confirmation message.
Here are just a couple of approaches I could think of but they are not without flaw:
Whatcha Gonna Do technique
Detect the mouse position going towards the edges of the browser as the user might be going to close the tab, window, go back, navigate elsewhere among other things. If so, immediately prompt them that that may be a mistake and they are going to lose out on something very valuable. However, the catch here is that you don't know for sure what their intentions were and you might piss them off with that popup. Also, they might use a bunch of shortcuts such as Ctrl+W etc to do the same.
You've Got Mail technique
If you've managed to get hold of the user's email address before they closed the page, you've hit a jackpot. As soon as the user types anything into the email box and then leaves it, immediately send it to the server using AJAX. Save the state of the page into localStorage or on the server using a cookie or something so it can be recreated later. Every couple of hours send them an email giving them a direct link to the previously saved form, and maybe with special offers this time.
History Repeats Itself technique
Then there's the infamous history manipulation where you keep stacking the current page into the document history so the back button renders effectively worthless.
Don't Put All Your Eggs In One Basket technique
Another technique off the top of my head is to create multiple windows in the background with the registration form and keep them all in sync when any the fields in any one changes. This is a classical technique and really puts the "don't put all your eggs in one basket" saying into real-life usage.
Another advantage of this awesome technique is even if the user closes one of the windows, and later comes across an identical cloned window with all the fields they filled up-to-date populated, they might get confused and think that they never closed the page. And guess what, this time they might just go ahead and fill out the registration form. But you have to be cautious with this as anything more than 2 or 3 clones will make it obvious as to what's going on.
You're Winner technique
Another technique is to tell every user they they are the Xth visitor on the site and use a good rounded number for X such as 1000, 10000, 50000, etc. Tell them that they can claim their prize once they register on the site. Imagine how special each user feels when they land on your site. The prize doesn't have to be anything tangible, it can simply be free coupons that you find on the intertubes.
Where Do You Want To Go Today? technique 1
This is basically a rip-off of your answer. Use document.location.href = 'some url' inside your onbeforeunload callback to navigate to a different page before it is unloaded.
1 Firefox only.
Note: there is no silver bullet solution here unless you write your own browser with your own security policies, but these are all optimizations that you can do to make it utterly impossible for users to leave.
Not all browsers support a modal popup, without which your page would go ahead and navigate anyway.
This is real awful requirement. The sort of requirement that is reasonable in a desktop application but entire unreasonable feature of a web site. Imagine being unable to leave a website.
The answer is either use the horrible confirm box and lump it. Or don't ask the user to enter too much data per page. Use a step by step wizard style data entry, the loss due to accidental navigation is minimised.
You can change the Value of the url using document.location.href = "www.website.com"
I can accomplish this feat using confirm boxes, but the client says that they are too ugly.
If the problem is the ugliness of the standard JS popup boxes, try something like this: http://www.sohtanaka.com/web-design/inline-modal-window-w-css-and-jquery/
Apart from that I second what most people are saying: do this with extreme caution if you don't want to lose users.

Adding Template Select and Image upload to custom post in Wordpress

I have become a bit confused on the best way to move forward with something I'd like to achieve in Wordpress. My problem is partly workflow I think and knowing the correct way to do what I'd like to achieve but also there may be a few blanks on how to actually implement some of what I need to do. I have checked various online resources but they all are specific to what they are doing and I can't easily understand them to apply them in to the context of my own project, which is why I wanted to ask here. I'm sure my initial question will inevitably branch out to sub questions but here we go:
For my website I have created a custom post type called 'projects'. I have successfully set this up.
Then for each project I need to allow the following data to be entered:
Project Title
Project Description
Also post meta data that will display as a list on each project page (I'll need to display both the key and value on the page but only for those fields that contain data 'i.e. I don't want the list to show as Location: blank'):
Client Name:
Location:
Project Value:
Architect:
Engineer:
Site Area:
My main question is this, I need to show images for each project and allow the user to select a 'template' for each project post, this is because there are about 5 grid designs for layout of the images (1 main Image, 1 square image with two small images right side, 3 portrait image cols etc).
I thought the correct way would be to create a custom post type called projects, add write panels to allow easy input of data (I've yet to add image uploads as this will need to vary depending on the template selected and number of images required), at data input stage the user selects the preferred image layout/template and then uploads images for the containers that allow images (I’ll need to id each image upload to position it in the template with CSS, that was the plan).
Firstly, am I approaching this correctly? And secondly, how can I add functionality to the write panel I have created to allow users to a) select a 'Template' (bit like you can with pages but for my custom post type) and b) to add image upload fields which change depending on the template selected?
Finally, I would like to stay away from using plug-ins and try and achieve this myself through functions.php etc. This is to avoid problems later as plugins update or lose support etc.
Any help is appreciated, thank you.
This sort of question seems to come up a lot in regards to Wordpress (I answered essentially the same question the other day). I know you want to avoid plugins but this sounds like a job for Advanced Custom Fields.
You can create exactly the fields you need for your custom post type (including an image upload field), and then add them into the template the corresponds with your custom post type.
ACF does have a 'lite mode' which can be included directly in a theme. This way you needn't worry about updates nuking site functionality. Believe me you will save yourself a lot of time and energy this way.
It's admirable to try and do it with pure WP, but it's a maturing platform, it just doesn't lend itself to this sort of customization easily.

How could I allow copy editors for my Django site to create internal links in a DRY manner? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
My Django site is an ecommerce store. Relatively nontechnical copy editors will be logging into the Django admin interface and writing the copy for each of the product pages. They have told me that they want to be able to create links in this copy to other pages on the site. For example, if a product references another product in its description, they want to link between the pages.
I see a couple of possible options:
They simply hardcode the urls in <a> tags in the copy. I've set up ckeditor for the admin textareas so this would be the simplest solution, but if the url structure of the site ever changed, (say we changed them for SEO purposes) all the links would break.
Introduce some sort of wiki syntax where they surround the text that they want the links to be in square brackets. Something like:
Widget A works really well with [[Widget B]]. It is good.
would produce:
Widget A works really well with Widget B. It is good.
Then you have the problem of what happens if the product's name changes?
Has anyone dealt with this problem before and come up with a solution that is flexible enough to allow changing links/names/etc?
I deal with this issue frequently. Ultimately, you have to be very persuasive to convince me to allow embedding links directly into the copy--especially with an e-commerce website.
What if the product name changes or is re-branded?
What if the product is discontinued... you don't want 404 errors from your internal links.
Do you really want to lead people away from your "add to cart" call to action that high up on the page?
Do they know your SEO strategy? Are they going to dilute your links? What verbiage will they use? Will they ensure the link is valid?
When I am asked to give copy/product development team the ability to add links I always start with a No. Ask them what they need them for, explain the problems that can arise (eg. extra cost in maintaining valid links, conversion rate considerations, SEO considerations), and offer alternative solutions.
For example, I usually offer the ability to allow them to associate products with products as "Associated Products", "Related Products", "Accessories", "More Information" etc. You can have these in tabs or lists at the bottom of the product page. These would be in models and thus you have control over not displaying discontinued products, the link names are the product names (which you have SEO control over), etc. Determine if they are going for cross-selling, up-selling, or providing the end user with more information.
As a last resort I have also used a custom code parser which is again based on the target object and not a hard-coded link. For example, let's say you give them the ability to do:
Widget A works really well with [product=123].
A custom template tag, parser in your model/view can replace that with a link to the the Product with id=123 (or use slug) based on get_absolute_url(). If the product is discontinued, the name can still show but no link. This only works if you have a policy of never deleting records. Even then, you may have to have some error handling for when they enter an invalid product ID or somebody does delete that product. That will happen.

How can I prevent automatic form submission by bots?

I am running ColdFusion MX, so I don't have the possibility of using the built-in cfimage Captcha functionality in my application, before form submitting.
But the problem is without captcha the bots submit the forms.
What will be best way to prevent automatic submitting?
Captchas don't have to be images!
Try one of the following solutions:
Most bots don't understand CSS. Create two submit buttons, the first with a value that will be rejected by the server, the second with a value that will be accepted by the server. Hide the first one using CSS.
Ask the user to answer a simple math problem. This will require you to create the math problem and store the expected solution somewhere (like the user's session), then compare the user's submitted answer with the stored answer. For extra protection, you can create simple addition, subtraction and multiplication questions. Avoid division, remainders are a pain for some users.
Bots read the names of form elements, and tend to ignore text labels. Try creating a checkbox named "optout" (like a newsletter), checked by default. Next to the checkbox, ask the user to uncheck the checkbox if they are a human. The opposite technique also works (unchecked checkbox that you ask the user to check).
All of these solutions can be done without third party code or API calls.
That being said, reCAPTCHA is pretty good and easy to integrate into almost any environment.
Take a look at cfformprotect - it will work with CFMX 6 and all later engines.
It aims to be fully accessible - and invisible to most users - with an assortment of methods to stop bots and spammers.
Also you might want to look at a CF wrapper for reCaptcha, which is compatible with CFMX 7.
A technique I used with a different technology was to use image buttons. Your POST handler gets the x,y co-ordinates where the images were clicked. I found the bots (which are just generating post requests) were passing 0,0 and by dropping those requests on the floor I brought the spam posts down to less than the real ones. Sorry that I don't know how to do that in CF but I hope the technique is useful to you.
Its always a good idea to do data validation on the server side before processing no matter which solution you use.
This post may help: http://www.bennadel.com/blog/405-Fully-Accessible-Spam-Form-Submission-Blocking-Using-ColdFusion-And-X-HTML-Version-III-.htm
How about using calculation method? Just like 8 + 5 = ?
OR
how about using ColdFusion.Ajax.submitForm?