I want implement feature: saving the city of an unregistered user in my django app.
Example
I visited the site for the first time. And chose my city. (not registerd)
I visited the site for the second time. Site identified my city.
How can I do It with django?
P.S. Could you please recommend articles or materials?
Example of the site https://edadeal.ru/
(you can chose city in the top right corner red text)
Have the user enter their postal/zip code first, in a popup.
Then, I would use a webservices API like EZCMD.com
to get a list of nearby cities, which the user will then select based on their postal code.
Then store that list in a cookie along with an anonymous user unique token. When the user comes back to the site, check for the cookie.
Check the token against your database for people who have visited the site and entered their postal/zip code.
To get the list of cities to put in your form you can do something like:
$.getJSON('https://ezcmd.com/apps/api_geo_postal_codes/nearby_locations_by_zip_code/GUEST_USER/-1?zip_code=90210&country_code=US&unit=Km&within=5', function(data){
//extract the data you need for your form here. This API might be best for the US,
//don't know about Russia.
console.log(data);
});
See jsfiddle to play with the API.
You can use this to set a cookie
Use this to set a unique token
I would recommended reading this question to understand how to retrieve IP address and location via GeoIP. This can then be stored as part of a model within the db.
You could get the code to check the db to see if the IP has previously appeared and if not then store it with the associated city.
I have a webapp that allows authenticated as well as anonymous users to start entering some form data. If a user is happy with his/her input, he/she can save that form to the server. This is a very similar problem to a shopping cart application that does not require login until checkout time.
For the authenticated user, implementing a save button is trivial. However for the anonymous user, the form data need to be stored somewhere while authentication is taking place, then correctly retrieved after logged in. Can someone please suggest some general strategies to go about this?
I found this link that is promising but I want to be thorough about this topic.
I think the correct way of doing this is to use django sessions. Basically each user (anonymousUser included) has a session during its stay on the website (or even more).
If you have a form that you want to store for a specific session, you can do it by using
request.session['myform'] = form
you get it by
request.session['myform']
and you can delete it using
del request.session['myform']
Basically Django pickles a dictionary of the session and saves it in a place (typically the database, but can be on other place as explained in django sessions).
I need some advice / ideas if someone is inclined to help: I have a javascript interface for manipulating pictures. Basically it's about moving photos around. Once it's done the position of images is saved into a Django form and then saved to database with the owner saved as the current user. Now the trick is that I would like to be able to allow non registered users to play with this interface and then if they like the result they hit save and are redirected to an account registration page and only then the form is actually saved with their user as the owner.
What comes to my mind now is to keep the values of the form in session but I don't know what will happen to the session once the anonymous user registers and becomes another user. I was also thinking of using a 'next' parameter in the registration process with the url filled with get parameters that would be the content of the form but then I don't know if userena is ready to allow that.
Any light on this is welcome.
Well, we did similar thing on our site.
When unregistered user attach photos we save objects to database and assign unique hash which was generated when user came to the page with form. When user hit submit we pass this hash in url and on the next step, when user wants to register, we just get objects from database by this hash and assign user_id to them.
Also we have a cron job which do clean up and removes all lost objects
P.S. Sorry for my english i hope you'll get my point
Save the object without the user and store a reference of that object in the session (or (signed) cookie). If if the user registers, update all the objects with the newly created user.
Another approach would be to store the data in the browser (html5 localstorage and fallbacks, or similar) and only insert it into the database once the user has signed up. You would need to make sure both things happen inside the same browser 'instance', but things would be easier in the server side.
Scenario:
I have an administration-application which manages the user accounts for another application. Now I would like to place an user-specific-link (e.g. Click here to login with user1) in the administration-application allowing the admin to directly log in with the user in a separate browser window or tab (target="_blank").
Problem:
When the admin clicks two or more links and opens two tabs with tab1=user1 and tab2=user2, the last clicked tab overwrites the session-variables of all other tabs. Sure... that's how sessions work, but I wonder if there is a way to let the admin manage multiple user interfaces with one session in multiple tabs? But I don't see a possibility to identify a specific tab in the browser so that I could say "in tab1 is user1 and in tab2 is user2 logged in ...
Question:
Has anyone done something similar and likes to share the basic idea of solving this?
EDIT:
One possible solution could be to add an parameter to the URL with the userid and hand it through to every page, right?
As your edit points out, the way to do this is with a url variable that specifies who the user should be.
There are a number of security issues with this approach tho.
I'm assuming that your initial link is doing some sort of security check to make sure that the initial "log in" of the user is an authorized request. You'll need to do a similar thing for this method. If your initial request is something like http://example.com/page.cfm?userid={id}&authtoken={encryptedtoken} I would then put that userid into the session scope as a valid userid that the admin can impersonate. The more links they click on the more users they can impersonate. On subsequent requests you check the requested userid against the allowed list in the session and either allow or deny the impersonation.
You'll also need to update all the links on the site so that they include the userid in them. The easier way to do this is to cheat and user jQuery or such to rewrite all internal urls with the userid appended. You would conditionally include that javascript based on the above check.
Lastly you'll likely want to prevent these urls that include the userid from appearing in search engines, if it's not a fully locked down site. You'll either need to use canonical urls to remove the userid, or set x-robots headers to tell search engines not to index the urls where the userid has been specified; or both.
That's the most primitive method of getting different "sessions" for multiple users in the same browser. However you'll then bump into issues if you're using the session scope for anything meaningful, because each tab will try overwriting the other. You'll need to overwrite the normal site session variables on each request, or you'll need to create different structures in the session scope for each userid that is used. How much of a problem this is depends on your application.
It's a do-able thing, but probably a lot more work then you were hoping for.
The other option is to get the admins to use Google Chrome with multiple profiles and copy and paste the login url into different profile windows. A slight inconvenience for them, but a lot less work for you.
You're building a web application. You need to store the state for a shopping cart like object during a user's session.
Some notes:
This is not exactly a shopping cart, but more like an itinerary that the user is building... but we'll use the word cart for now b/c ppl relate to it.
You do not care about "abandoned" carts
Once a cart is completed we will persist it to some server-side data store for later retrieval.
Where do you store that stateful object? And how?
server (session, db, etc?)
client (cookie key-vals, cookie JSON object, hidden form-field, etc?)
other...
Update: It was suggested that I list the platform we're targeting - tho I'm not sure its totally necessary... but lets say the front-end is built w/ASP.NET MVC.
It's been my experience with the Commerce Starter Kit and MVC Storefront (and other sites I've built) that no matter what you think now, information about user interactions with your "products" is paramount to the business guys. There's so many metrics to capture - it's nuts.
I'll save you all the stuff I've been through - what's by far been the most successful for me is just creating an Order object with "NotCheckedOut" status and then adding items to it and the user adds items. This lets users have more than one cart and allows you to mine the tar out of the Orders table. It also is quite easy to transact the order - just change the status.
Persisting "as they go" also allows the user to come back and finish the cart off if they can't, for some reason. Forgiveness is massive with eCommerce.
Cookies suck, session sucks, Profile is attached to the notion of a user and it hits the DB so you might as well use the DB.
You might think you don't want to do this - but you need to trust me and know that you WILL indeed need to feed the stats wonks some data later. I promise you.
I have considered what you are suggesting but have not had a client project yet to try it. The closest actually is a shopping list that you can find here...
http://www.scottcommonsense.com/toolbox.aspx
Click on Grocery Checklist to open the window. It does use ASPX, but only to manage the JS references placed on the page. The rest is done via AJAX using web services.
Previously I built an ASP.NET 2.0 site for a commerce site which used anon/auth cookies automatically. Each provides you with a GUID value which you can use to identify a user which is then associated with data in your database. I wanted the auth cookies so a user could move to different computers; work, home, etc. I avoided using the Profile fields to hold onto a complex ShoppingBasket object which was popular during the time in all the ASP.NET 2.0 books. I did not want to deal with "magic" serialization issues as the data structure changed over time. I prefer to manage db schema changes with update/alter scripts synced with software changes.
With the anon/auth cookies identifying the user on the client you can use the ASP.NET AJAX client-side to call the authentication web services using the JS proxies that are provided for you as a part of ASP.NET. You need to implement the Membership API to at least authenticate the user. The rest of the provider implementation can throw a NotImplementedException safely. You can then use your own custom ASMX web services via AJAX (see ScriptReference attribute) and update the pages with server-side data. You can completely do away with ASPX pages and just use static HTML/CSS/JS if you like.
The one big caveat is memory leaks in JS. Staying on the same page a long time increases your potential issue with memory leaks. It is a risk you can minimize by testing for long sessions and using tools like Firebug and others to look for memory leaks. Use the JS Lint tool as well as it will help identify major problems as you go.
I'd be inclined to store it as a session object. This is because you're not concerned with abandoned carts, and can therefore remove the overhead of storing it in the database as it's not necessary (not to mention that you'd also need some kind of cleanup routine to remove abandoned carts from the database).
However, if you'd like users to be able to persist their carts, then the database option is better. This way, a user who is logged in will have their cart saved across sessions (so when they come back to the site and login, their cart will be restored).
You could also use a combination of the two. Users who come to the site use the session-based cart by default. When they log in, all items are moved from the session-based cart to a database-based cart, and any subsequent cart activity is applied directly to the database.
In the DB tied to whatever you're using for sessions (db/memcache sessions, signed cookies) or to an authenticated user.
Store it in the database.
Do you envision folks needing to be able to start on one machine (e.g. their work PC) but continue/finsih from a different machine (e.g. home PC)? If so, the answer is obvious.
If you don't care about abandoned carts and have things in place for someone messing with the data on the client side... I think a cookie would be good -- especially if it's just a cookie of JSON data.
I'd use an (encrypted) cookie on the client which holds the ID of the users basket. Unless it's a really busy site then abandoned baskets won't fill up the database by too much, and you can run a regular admin task to clear the abandoned orders down if you care that much. Also doing it this way the user will keep their order if they close their browser and go away, a basket in the session would be cleared at this point..
Finally this means that you don't have to worry about writing code to deal with de/serialising the data from a client-side cookie, while later worrying about actually putting that data into the database when it gets converted into an order (too many points of failure for my liking)..
Without knowing the platform I can't give a direct answer. However, since you don't care about abandoned carts, then I would differ from my colleagues here and suggest storing it on the client. Why store it in the database if you don't care if it's abandoned?
Then again, it does depend on the size of the object you're storing -- cookies have their limits after all.
Edit: Ahh, asp.net MVC? Why not use the profile system? You can enable an anonymous profile if you don't want to bother making them log in
I'd say store the state somewhere on the server and correlate it to the user's session. While a cookie could ostensibly be an equal place to store things, if you consider security and data size, keeping as much data on the server as possible becomes a good thing.
For example, in a public terminal setting, would it be OK for someone to look at the contents of the cookie and see the list? If so, cookie's fine; if not, you'll just want an ID that links the user to the data. Doing that would also allow you to ensure the user is authenticated to the site in order to get to that data rather than storing everything on the machine - they'd need some form of credentials as well as the session identifier.
From a size perspective, sure, you're not going to be too concerned about a 4K cookie or something for a browser/broadband user, but if one of your targets is to allow a mobile phone or BlackBerry (not on 3G) to connect and have a snappy experience (and not get billed for the data), minimizing the amount of data getting passed to the client will be key.
The server storage also gives you some flexibility mentioned in some of the other answers - the user can save their cart on one machine and resume working with it on another; you can tie the cart to some form of credentials (rather than a transient session) and persist the cart long after the user has cleared their cookies; you get a little more in the way of fault tolerance - if the user's browser crashes, the site still has the data safe and sound.
If fault tolerance is important, you'll need some sort of persistent store like a database. If not, in application memory is probably fine, but you'll lose data if the app restarts. If you're in a farm environment, the store has to be centrally accessible, so you're again looking at a database.
Whether you choose to key by transient session or by credentials is going to depend on whether the users can save their data and come back later to get it. Transient session will eventually get cleaned up as "abandoned," and maybe that's OK. Tying to a user profile will let the user keep their data and explicitly abandon it. Either way, I'd make use of some sort of backing store like a database for fault tolerance and central accessibility. (Or maybe I'm overengineering the solution?)
If you care about supporting users without Javascript enabled, then the server side sessions will let you use URL rewriting.
If a relatively short time-out (around 2 hours, depending on your server config) is OK for the cart, then I'd say the server-side session. It's faster and more efficient than accessing the DB.
If you need a longer persistence (say some users like to leave and come back the next day), then store it in a cookie that is tamper-evident (use encryption or hashes).