Django guests vote only once poll - python

I'm new to Django but am working on the tutorial on the Django website for creating a poll.
What is the best way to make it so guests (no registration / login) can only vote once on a poll?
IP (Don't want IP because people sharing a network can only vote once).
Cookie (User can delete the cookie but seems like the best approach).
Session (If the user closes the browser the session will change).
I'm guessing that Cookie would be the best approach but is there a better way for Django?

There is one solution independent on the server framework you use:
Evercookie gives you virtually irrevokable cookies. Use them, if you want that level of data persistence.
Evercookie is a solution for storing data in cookies and various other places (such as memory used by Flash "cookies", HTML5's LocalStorage etc.). If any of these places is cleared, next visit on the site will populate it with data again. The only thing you need is the data stored in any of 13 places used by Evercookie and next visit populates it again to the other 12 places.
It is pretty hard to get rid of such cookies, so please take into account, whether your users actually agree to be tracked that way. Some of them certainly would not agree.

If it is that important that people can only vote once, consider creating a basic registration / login system anyway. A guest can always use multiple computers to skew the voting while account registration at least allows you to track which e-mail addresses are being used to vote. It also takes a bit more effort to skew the voting that way. If it's important but not of life-saving importance then I would use the cookie approach for anonymous guests.

Related

Django Multi-site with shared database

I am about to develop multiple sites for different real estate companies. All share the same html, sections, etc. The difference is in the content, specially the properties... But some of those properties can be shared among the rest of the companies.
I am thinking in sharing the same database and differentiate content using the url. In this way I can use only one project instead of one for each company.
Does anyone have recommendations for this kind of projects?
Thanks,
I have done that.
Was it a good idea? Yes, in my case it was. I had to reuse the same content and when we changed the content, it had to be changed on all pages. On a simple site, a triple deploy and changing the content in three different projects is kind of overkill. But whereas it works fine in a simple front-end page (that hardly even requires Django), I do not recommend it for "real" web apps.
What will break? Think about the things that your pages will share and see if it's a problem.
1) I'm guessing that if you'll want to have user login capability on the page (besides the admin login), then that's a problem, if I can use the same user for different companies that have no apparent connection whatsoever. You could be in for a lot of trouble if the companies find out that user private details aren't as private as they thought. And the same goes for the users who really don't have a clue how they ended up with a user account on a page they've never visited.
2) URLs. You can't have different ones for each company without some extra hacking. If one of the companies wants to have /about/ and the other one /company/ page, you're gonna start hacking a bad solution that will blow up in your face when the companies ask for the next page.
3) Anything else you might want to have on your page that is connected to hardcoded data or database values. I.e. social authentication etc.
What can you do about it?
If I was hellbound on solving the first one, here's what I would do:
- Override the user model and add info about the registering page
- Create custom managers for user model for each page
- Write a middleware that only lets you use the page-specific manager for the current request
All in all, I wouldn't do it in a million years. Way too hacky, way too vulnerable. Just create separate databases.
For solving the second one, you can create a multi-host middleware that checks from which domain the request comes from and returns the correct URL config. Sth similar to this . It's not really hard to rewrite and modify to your needs.
It's impossible to decide for you, but I've given you something to think about before going one way or the other. Good luck!

Using Django's cache if and only if the user is logged-out?

I need to implement caching on my Django 1.8 site (to speed up rendering, obviously). Plan is to use Memcache, although this question isn't directly tied to it.
Right now, a lot of traffic goes to a specific set of blog posts that remain constant. But, there is a universal dynamic topbar across the whole site which can vary from logged-in user to logged-in user, so I need a cache function that kicks in if and only if the user is anonymous - e.g. one that is bypassed altogether if the user is logged in.
It looks like Django's builtin cache doesn't really distinguish between logged-in and logged-out users, so if I use it, there will be adverse effects for logged-in people.
I'll probably have to write my own cache decorator/cache function using the lower-level cache API and attach it to all of the logged-out-accessible URLs/views on the site. While it doesn't seem difficult, this does seem like an incredibly common feature. Is there really nothing in Django that does this properly already? I'm worried I might have missed something and am reimplementing the wheel.
Thank you!
First of all template caching is over rated. First use django debug toolbar to determine if template rendering is indeed slow on your django installation. I am betting that it's not the bottleneck. If you find that it's slow. YOu can cache on a per user basis as follows:
{% cache 300 FULL_PAGE request.build_absolute_uri request.user %}
The first parameter to the cache template tag is the timeout and the second one is the name others uniquely identify the fragment.

Django User Sessions, Cookies and Timeout

I'm working with a Django application and my current goal is to keep track of the user session with cookies. I have a feeling that, as always, my understanding is a bit off with regards to how I do this.
For starters, I would like to manage how long it has been since a user has logged in, that way I can successfully log them out if they haven't visited a new page in "x" hours. I am not sure what exactly is standard (for a social network).
Is this information I store on my server? Do cookies actually have any relevancy here? I've used cookies before to store things like a user's timezone, but I am struggling to deal with how I keep track of the user.
All I currently have in terms of user back end is from the django.contrib.auth package.
The only thing I really know how to do in terms of "grabbing" the user's info is done by using statements like if request.user.is_authenticated(): (etc.).
I realize this is somewhat of a complex question, so I will try and narrow it down:
How do I extend my existing information about the current user to capture "last activity" so I can log him/her out if they haven't been using the site in a certain period of time?
Do I need to define a custom user model?
My next step after is to create a different type of user, so I feel like I need to make custom user models - beyond just extending the normal user form to make a profile etc.
Thanks for your understanding,
I know I can be confusing when I don't understand things.
Thanks for your time,
James
You can configure the session middleware for logging out the user automatically,
configure the SESSION_COOKIE_AGE, to some low value, and provide the SESSION_SAVE_EVERY_REQUEST, as True.
This will automatically logout the user after certain inactivity, without any need of extending the profile.
SESSION_COOKIE_AGE
Default: 1209600 (2 weeks, in seconds)
>> The age of session cookies, in seconds.
SESSION_SAVE_EVERY_REQUEST
Default: False
>> Whether to save the session data on every request.
If this is False (default), then the session data will only be saved if it has been modified – that is, if any of its dictionary values have been assigned or deleted.
And for creating custom/extending User Profile, Django 1.5, comes with configurable User model, please check the docs for examples.

Django multi-user saas

I'm creating a small saas for learning purposes... I know that the best way to go is to have a separate schema for each user... But my saas is a small app and I really don't need separate schemas plus it would complicate stuff (later alterations to the schema)... So I'm going to use the same schema for all users and just append each user's ID to the entry and then display only the user's entries upon login.
Is there a way I can "prepend" user's ID upon login through middleware? Or do I need to adjust all the queries (filter by user's ID)? I already store the user's ID to his entries... so I need this only for select's.
Thank you!
I don't know of any way to automatically filter querysets based on request.user. This is because the ORM is not coupled with django.contrib.auth.
I tried two SaaS designs:
1 database for all sites, and manual filtering on all querysets. Of course this made django.contrib.admin not possible out of the box. It might be possible to enable django.contrib.admin with a really tight setup of django-authority or maybe even other django per-object permission packages (google cached version because djangopackages.com is down ATM).
1 database per site, that's just easier, keeps the code cleaner, and enables django.contrib.admin out of the box, which can be really cool if you install a django admin theme. Also I enabled django.contrib.admindoc as well as django-dbtemplates.
(Apparently in your case, 1 site = 1 user, but the concept is the same)
I prefer the second implementation because it's obviously a lot less development work, which is compensated by a little system administration.

How should I handle anonymous user input?

I'd like the users of my web application to not have to register a user account before they can vote. I've seen websites where I could freely vote up or down on what ever I want without having to register. How is this handled? How can I prevent the same person from voting infinite amounts of times?
I'm using Python and Django. I'm thinking of implementing facebook login, but I'd like to hear some of the experts' comments. I'll mark the most helpful answer as correct.
Don't rely on facebook login, as users without facebook will not be able to vote.
As there is no real way to be sure that an unregistered user will not vote twice (he can connect himself from another computer, or whatever), you have to define yourself what is the criteria you want to use to check his identity.
You have different ways to solve your problem, all of them rely on storing information about the user that voted. You can rely on ip address, or store information in session or in cookies to know if your users already voted or not.
I would create a session variable that will tell me whether they've voted or not. True, the user could clear their cookies and vote twice but that is an edge case. If you're letting them vote without registering I'm guessing the poll isn't too scientific.
Django has some good examples on their website about how to use sessions.
https://docs.djangoproject.com/en/dev/topics/http/sessions/#examples
This one in particular should be helpful to you. Instead of votes they're dealing with comments:
def post_comment(request, new_comment):
if request.session.get('has_commented', False):
return HttpResponse("You've already commented.")
c = comments.Comment(comment=new_comment)
c.save()
request.session['has_commented'] = True
return HttpResponse('Thanks for your comment!')

Categories