How can I track a user events in Django? - django

I'm building a small social site, and I want to implement an activity stream in a users profile to display event's like commenting, joining a group, posting something, and so on. Basically, I'm trying to make something similar to a reddit profile that shows a range of user activity.
I'm not sure how I'd do this in Django though. I thought of maybe making an "Activity" model that's OneToOne with their account, and update it through MiddleWare.
Anyone here have a suggestion? Away I could actually implement this in a nice way?

You pretty much need to use an explicit Activity model, then create instances of those records in the view functions that perform the action.
I think you'll find that any other more automatic way of tracking activity would be too inflexible: it would record events at the wrong level of detail, and prevent you from describing events in a way that the user wants to see them.

In my opinion, you should do exactly what you're saying, that is create the model Activity, which has a foreignKey to User which you will populate triggering the things you'll find 'interesting'.
This practice, even if redundant, will speed up your page generation, and you can add a custom field which will hold the text you want to display, and also you can keep track of what generate the Activity.

Related

django change the default query set based on the requesting user

I have a system with multiple organizations logging in and interacting with us and our partners. I have a table that keeps track of what users have access to what organizations. I would like for customers to only see their own records.
I am doing this inside the views and whatnot. However, I find myself often trying to code around this. It makes it so I can't use some of the generic views as easily. Forms are a pain because when a field is pulled in as a dropdown option if shows all the records. In reality, I never want to receive all the records back. I would much rather the query check the access table and always just return what a user has access to.
I have seem some mentions about using a middleware change but I would really like to keep this within the manager and query set. It seems like that is what they are there for. However, I can't seem to find a way to reference request.user without passing it in (this causes other changes and messes with all my forms....).
Is way to do this within the manager and queryset?

Sitecore 6 Filtering Items based on a profile

I am looking for a generic method of filtering a series of sitecore items based on the users current profile, I found one promising example:
How do I trigger a profile in Sitecore DMS?
However a few critical references are missing which is a shame as it looks to be a suitably generic function
Resources.Settings.AnalyticsUserProfileEnableSwitch I assume to simply be a boolean switch
The killer is ApplyUserProfile(filter)
Please keep in mind that user profiles are NOT the same thing as profiles in DMS. In DMS this is in reference to Analytics profiles related not to the specific user, but in visiting profiles... i.e. Marketing personas.
If you want to filter items based on user profiles, you simply get the Sitecore.Context.User.Profile and get whatever the property is and implement your logic to how you want to filter.
If you want to filter items based on DMS profiles, then that's something that's going to be difficult to do due to the fact that personas are not entered into the Analytics database real time. Those really aren't something you'll even be aware of at run time and therefore it's going to be difficult to categorize the persona at run time. You could, however, use the rules system to do some filtering based on other criteria (such as using the Engagement plans or something else)... but without more information, that's about as much as can be said.

discovering which admin performed an action in Django

I am trying to set up a system where every time something happens in the admin console (let's say, a user is saved), a certain set of people gets notified. I hooked up post_save and
it works fine. I can retrieve most of the data I need (which user and what fields were saved) from the instance passed into the callback function. However, there's one thing in the requirements, which I can't figure out how to do and that is to show, which particular admin made the change. Any ideas on how that can be done?
Thank you,
Luka
If you go through the database, you will discover that you have the table django_admin_log which lists what changes were made by what admin and even has a change_message . Maybe you can create a view for this table and play around with the queries.

Marking users as new when created via a backend's authenticate in Django

I have an authentication backend based off a legacy database. When someone logs in using that database and there isn't a corresponding User record, I create one. What I'm wondering is if there is some way to alert the Django system to this fact, so that for example I can redirect the brand-new user to a different page.
The only thing I can think of is adding a flag to the users' profile record called something like is_new which is tested once and then set to False as soon as they're redirected.
Basically, I'm wondering if someone else has figured this out so I don't have to reinvent the wheel.
I found the easiest way to accomplish this is to do exactly as you've said. I had a similar requirement on one of my projects. We needed to show a "Don't forget to update your profile" message to any new member until they had visit their profile for the first time. The client wanted it quickly so we added a 'visited_profile' field to the User's profile and defaulted that to False.
We settled on this because it was super fast to implement, didn't require tinkering with the registration process, worked with existing users, and didn't require extra queries every page load (since the user and user profile is retrieved on every page already). Took us all of 10 minutes to add the field, run the South migration and put an if tag into the template.
There's two methods that I know of to determine if an object has been created:
1) When using get_or_create a tuple is returned of the form (obj, created) where created is a boolean indicating obviously enough whether the object was created or not
2) The post_save signal passes a created paramater, also a boolean, also indicating whether the object was created or not.
At the simplest level, you can use either of these two hooks to set a session var, that you can then check and redirect accordingly.
If you can get by with it, you could also directly redirect either after calling get_or_create or in the post_save signal.
You can use a file-based cache to store the users that aren't yet saved to the database. When the user logs in for the second time, you can look in the cache, find the user object, and save it to the database for good.
Here's some info on django caching: http://docs.djangoproject.com/en/dev/topics/cache/?from=olddocs
PS: don't use Memcached because it will delete all information in the situation of a computer crash or shut down.

Filtering of data according to user logged in Django app

I have a Django app that works well for me, but currently has no notion of user: I am the only one using it, and I would like to change this...
Except for the admin views, the logged-in user should not have access to the data created by other users. There is no shared data between users.
I suppose I have to add a user foreign key to all the models I created. Correct?
Is there a simple way to implement the filtering based on request.user? Can this be done more or less automatically, or do I have to go through all the code to check each and every query done on the database?
I have written the code using TDD, and I intend to follow up... What are the best strategies to ensure that user-filtering is implemented correctly, e.g. that I did not forget to filter an existing query? I suppose I can write tests that show that a particular query is not yet filtered, and implement the filter. But what about the queries that I will write later? Is there a way I can assert that all existing and future queries return objects that only belong to the current user?
Thanks.
Yes, you'll need to add a User FK. Don't forget you'll have to migrate your database tables - either manually, or via a tool like South.
One way of implementing the filter would be to define custom Managers for your models, with a for_user method that takes the User as an argument: something like:
class ForUserManager(models.Manager):
def for_user(self, user):
return self.filter(user=user)
Now you can use this manager - subclassed and/or with a mixin as necessary - on all your models, and remember to use objects.for_user(request.user) everywhere.
This will make testing easier too - your test could monkeypatch that for_user method so that it sets a flag or a counter in a global variable somewhere, and then test that it has incremented as expected.
Edit in response to comment No, as you suspect, that won't work. It's not even that everyone will necessarily get the last-logged-in user: it's that Managers are class-level attributes, and as such are reused throughout a process, so any request served by that server process will use the same one.