Which is the best way to log user actions in flask views? - python

I would like to log user actions whenever user logs in/out and adds, edits, deletes objects in my site models in flask. Which is the best way to do this? Also I would like to show the old data and the new modified data, which happens using wtfforms. I am using flask and Flask-SQLAlchemy. I want something similar to what Django framework offers in the 'History' hlink for the associated objects.

Use Signals. Take a look at this
http://flask.pocoo.org/docs/signals/
Using signals, you can keep track of any actions such as adds/edits etc. as needed. All you have to do is
from blinker import Namespace
my_signals = Namespace()
def add_user():
# add user code here
user_added = my_signals.signal('user-added')

You can refer to flask-login, also using Signals.

Related

Flask - User to Profile Relationships

I'm working with Flask-restplus and I am at a point where I would like to associate each User in my user model to a type of profile, where each user can be associated with one or many profile types. I'm wondering how you guys would go about this. So far, here's what I'm thinking/planning to do. NOTE: I'm not very experienced in web development, so there's a chance I don't know the best way to accomplish this.
Step 1: Create a one-to-many (clients need to also be employees, see below) field (profile_types) relating to a static table that just lists all possible profile options. EXAMPLE:
PK PROFILE TYPE
1 provider
2 employee
3 client
.....
The idea here is to track different information and allow for different views/endpoints for users who are tied to certain profile types. Example, employees would provide a valid login authentication and be directed to page A while a client would be directed to page B, etc. We're also planning on collecting different data points within each profile model.
So an instance of a user might look like this, user1.profile == [client, employee'].
NOTE: This is more important for data collection (ie age of employee, start date, etc) than it is for creating directives based on permissions.
Step 2: Upon creating the new user, a signal fires off the creation of a profile based on the profile_types supplied to the user instance. I've used signals with django in the past, is there a signal library for Flask?
Step 3: An empty profile instance(s) now exists for that user. It will be up to a superuser to upload data in bulk or manually fill out profile information.
Is this a sensible way to go about this? My other though is to create a bunch of Boolean fields in the User model is_provider, is_employee, is_client, etc. All fields that are True get assigned a profile instance. What's the best way to go about this?
Thanks everyone!
Seeing that are you try to validate multiple profile types, you may use
if user.profile_type in ['employee', 'client']
Now, if you want to add an super user I think you can use this
if user.profile_type in ['employee', 'client'] and user.profile_type == 'superuser'
Now, you relationship is more like 'many-to-many', because you are saying that an client also needs to be an employee, if you mean that some endpoints needs to be accessible for employees and clients, then you need to use a 'many-to-one' relationship (an Stackoverflow question which explains what is that)
For your instances, there is Flask Marshmallow, which has an amazing compatibility with Flask SQLAlchemy if you are using an database, but Flask Marshmallow can work alone.

Django pure controller functions

I am wondering on how to implement pure controller functions in a Django's' "biased" MVC scheme. Let me explain it on an example.
Let's say I have a model of an Invoice, which has some attributes (say net, gross etc.). I can present it to the user using a view + template. And that's fine and easy.
But now, I want to send this invoice to a client. This is a more complicated thing, inluding more models (i.e. create an addressed Package model, get a number and let's say few other thing including creating and modifying not only Invoice model itself, but also creating and updating few other model types and instances.
I want this "action" to be available in multiple places of my web application, so going by the book I need to create a view with those actions implemented and bind it to some URL. Probably it should be implemented in POST action.
My questions are:
What kind of generic view should it be (just View? DetailView? other?).
Where should this View redirect after succesfull "send"? The simplest answer would be to redirect to the same referring page, but is this a correct way?
What if I want this "action" to be ran in background (say, send all unsend invoices at midnight) using celery or such? Of course I can make this a celery task and call it in a view. But is this clean django'ish solution? Where do you store such pure business methods in an app/project?

Using the Django scheduler app with your own models

Using the https://github.com/llazzaro/django-scheduler I'd like to use my own models in the calendar, they also have a start and end date.
I think there are multiple ways to solve this problem:
Hack the current schedule app to make it interact with my models.
Creating default event models when creating my models, using the save() override.
Use the "relations of events to generic objects" feature of the django-scheduler app.
Extend the default event models to meet my own requirements.
I would like to use the third option but I wouldn't know how to use it since a calendar is linked to a single object.
I'm new to both Python and Django, so could someone give me advice?
To achieve option 3, your generic object would have a foreign key linking to an Event object from that calendar app.
Django Scheduler has a quite hidden setting (not even reported in official docs) which can do the trick:
SCHEDULER_BASE_CLASSES
SCHEDULER_BASE_CLASSES = {
'Event': ['my_app.models.EventAbstract1', 'my_app.models.EventAbstract2']
'Calendar': [my_app.models.CalendarAbstract']
}
So, you can define your own abstract model and make Calendar extend it.
EDIT
As #Jheasly said in his comment, this feature is now documented.

how to log model inserts,updates and deletes in django

how to log model inserts,updates and deletes?
I am not using django admin,in my app there are multiple tables
i just want to records only which model or table name, field name,previous value,who edited,and what time
to log table?
Who edited (my app uses SSO,it should pick up remote user automatically)
can you please suggest any built in function or module in django to records this kind of logs ,if possible can you plz add few lines of django code or any ref links?
Thanks in advance
You can try this:
from django.db.models.signals import post_save
def logging_function(sender, **kwargs):
# do your logging
post_save.connect(logging_function)
Python has a logger http://docs.python.org/library/logging.html What's wrong with that?
You can, also, add an event table to your Django models and write to that table.
For real fun, you can create a decorator which writes to that table.
You can search, too. You'll find things like this: http://djangosnippets.org/snippets/2111/

Set and use flags against a users profile model in Django

I have a simple webapp in Django for an iPhone app.
I want to prompt the user to review our product, but just once. I then don't want to show that prompt again.
So would the best practise way of implementing this to be to add a new entry to the user profile model with a bolean field: "reviewed" - and then set that flag when the user completes the action?
I would then check for that entry in my template and display or not, the prompt.
I've not yet worked with database models, extended the user model, or saved to custom DB fields, so any thoughts or examples on this would be most welcome. I'm a little nervous as my site has live users and I won't want to break the user tables.
If you are using MySQL or PostgreSQL, you can do some ALTER TABLE without loosing any data.
In Django, it is quite easy to add a profile for the user.
Make sure, to create the profile if it doesn't exist :
try:
profile = request.user.get_profile()
except UserProfile.DoesNotExist:
# If DoesNotExists, Create an empty one
profile = UserProfile(user=request.user)
profile.save()
More information here :
http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users
http://www.djangobook.com/en/1.0/chapter12/#cn222
There are a variety of ways to do this. I suggest the following:
Django has a messaging framework, built by design to show messages to users only once when the software creates them. Whenever X is created/modified/deleted etc, you can add the message to the user via User.message_set.create(message='Whatever you like'). This will be shown to the user once. This relies on django sessions, which I assume you're using since you're relying on the built-in user model. These messages are stored in auth_message.
HTH

Categories

Resources