Flask - User to Profile Relationships - python

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.

Related

In Django , How to handle multi user types with more than 1 user has access to same content?

In a Django Application, I have a model called application.py which is created by a user say "u". I want to list all the application created by the user "u" later, so i may need to add a reference to the model application.py from user.py.
I have one more requirement , as an admin , i need to provide access to any number of users to the same applications. So I assume this can be done with many to many relation.(Since users can access many applications).
Now the question is , is it possible to implement this behavior with user groups ,with one group is responsible for handling one application, so that in a later point of time i can add as many users as needed from the backend to respective groups to manage the same application.?
Which one is better , managing the users using many to many relation with model application.py or relating a group to application.py
and managing users using groups.
There are multiple ways to solve this, but it from a future flexibility point of view this sounds like a Role, Permission and Group relationship:
Applications have a many-to-many relationship to Users through a Membership.
Each membership would point to a Role. That could be hard-coded to start with (just a string like 'admin' or 'viewer').
This way a User can be associated to an Application as viewer or as an admin.
In the future, to add flexibility, you would have a model Role that describes the role (and could be associated to one or more Permission models to list the permissions for each role). So Membership would have a pointer to Role via a ForeignKey.
Check the documentation on extra fields on a many-to-many relationship.
There are also packages that solve this problem, e.g. django-permissions and django-role-permission

How to add to google app engine flask website the user registration ability if it wasn't scheduled in application architecture

I created website-app for myself and it become really useful and many peoples wont also use it. But user management was not scheduled in application architecture. Is there any way to easy add user registration so each user would have his own google database tables but with same name?
example of one "table":
class Settings(db.Model):
email = db.StringProperty()
link = db.LinkProperty()
rating = db.StringProperty()
How can I separate data from this "table" between different users? I search for some kind of wrapper so I don't need to change current architecture.
You have to remember there is no concept of tables with the datastore so you can't have a separate set of tables for each user as such.
You have a few choices, the two I would investigate are
create a separate app with the existing code base and each user runs their own site. You may not need to do any code changes at all
If you want complete separation of data for each user in a single app then look at namespaces (thats how multi-tenancy is normally implemented.)
However you haven't really provided a clear definition of how you want to separate the users etc.. so there a probably other approaches you can take.
Short of having a copy of the database for each user; you'll have to implement some code changes.
The easiest one you can do is add a foreign key to your data tables that points to your user table; then you filter all records based on this foreign key.
Once you have that change, you can write a view decorator that will automatically filter the records for you.

Django custom user VS user profile

I'm currently using Django 1.5.1 and using a custom user as described in the official documentation. I realized everything is stored under one table, the auth_user one.
My question is, why is it better to have everything in one big table, instead of having 2 tables like it used to be prior to 1.5 by using a user_profile table for all additional data? It seems smarter the way it used to be, in case we want to add 20 new fields for information about the user, it is weird to have everything in auth_user.
In my case, for now I have class MyUser(AbstractUser) with 2 additional fields gender and date_of_birth, so it's all good with this, but now I would like to have many other information (text fields) like "favorite movies", "favorite books", "hobbies", "5 things I could not live without", etc. etc., to have way more information about my user. So I was just wondering if I should put that under MyUser class, or should I define a UserProfile one? And why?
Thanks!
When you have it all in one table, then database access is faster. With the old way you had to join on the auxiliary table to get all the information of the user.
Usually when you see a One-to-One relation, it would be better just to merge them in one table.
But the new custom User model solves also another problem, which is what atributes a User should have? What attributes are essential for your application? Is an email required? Should the email be also the username with which a user logs in?
You couldn't do these stuff before this feature was introduced.
Regarding your question about where to put additional user information like "hobbies" and such, it really depends on how often you will query/need this attributes. Are they gonna be only on the user's profile page? Well then you could have them in a seperate table and there wouldn't be much problem or performance hit. Otherwise prefer to store them on the same table as the User.

Django: Using django.contrib.auth for SAAS ( Users, permissions, etc. )

I'm making a SAAS and I've been asking a slew of questions on here related to the Auth system built in. I'm having trouble understanding the "why" and "how". Primarily I don't understand how it fits in with my SAAS.
I (do) know the following:
You can do this: http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users
There are many reasons to use the built in auth system (like security) instead of rolling your own
I (don't) know the following:
class MyUserProfile(models.Model):
"""
Administrator for an Account. Can edit tickets and other stuff.
"""
user = AutoOneToOneField(User, primary_key=True)
account = models.ForeignKey(Account)
dogs_name = models.CharField(max_length=255)
In the previous example, account is just what you'd expect; an entity that's paying to use my software. user is my main concern. Somebody goes to a page and creates a UserProfile with a username and password, etc. When they do this, where does the related User get created? Do I need to create it in my view manually based on the request.POST['username'], etc, and then do
myuserprof = MyUserProfile.create(user=foo_user_just_created, account=foo_account, dogs_name='Spot')
I don't know why but for some reason I feel like I'm missing something. This idea of asking somebody to sign up for an account, and then create a MyUserProfile with a form that asks for the password, username, email, et al, and then in my view creating 2 different objects (MyUserProfile and User) with different parts of the form data. I mean I shouldn't have a User form right? Like I said, I feel like I'm either skipping a step or I'm in the wrong paradigm. I'm not new to Django, but for some reason I have trouble with things that I didn't build (I think it might be a mental problem for real at this point).
Maybe there is a good example of this sort of thing being done on some open source project.
Update: Oops, forgot to mention that in the code above I tried to use AutoOneToOneField from django-annoying, but I have no idea where all the User's attributes get set or how to decide which User object to attach to it. This stuff is driving me crazy.
Also, do I need to use the sites app to do this stuff, and finally does a "super user" have all permissions to everything (I don't want people from Account "Acme" to access account "Microshaft" objects)? Or do they just have all permissions to all views?
Somebody goes to a page and creates a UserProfile with a username and password, etc.
UserProfile doesn't have an username or password field. So it should be somebody goes to a page and create an User. Then, it creates an UserProfile associated to that newly created User.
The question is, how and when do you want this UserProfile instance to be created?
Automatically, whenever a new User is created : use signals, as described in the docs
Automatically, whenever the profile is accessed from an user instance : use AutoOneToOneField, and access the profile using user.userprofile instead of user.get_profile()
Manually. But don't forget an user might have no UserProfile associated yet, so user.get_profile() might raise a DoesNotExist exception.
When they do this, where does the related User get created?
It doesn't. You have to create it explicitely.
This idea of asking somebody to sign up for an account, and then create a MyUserProfile with a form that asks for the password, username, email, et al, and then in my view creating 2 different objects (MyUserProfile and User) with different parts of the form data. I mean I shouldn't have a User form right?
Why not? You want here to create an User and his associated profile in one go, right? You could eventually use directly the POST data, or use a Form to access to the fields, or even better, use 2 ModelForm (one for User, one for UserProfile) that you will process in the same view (maybe this question can help?)
Maybe there is a good example of this sort of thing being done on some open source project.
I suggest you check out django-registration and django-profiles.
Note
You have another way of adding information to an User object, by extending the model itsel. It will allow you to put your extra fields directly in the user model and might be easier for you to understand and use.
I won't dive into details here, have a look at that tutorial for more informations.
Other questions
I tried to use AutoOneToOneField from django-annoying, but I have no idea where all the User's attributes get set or how to decide which User object to attach to it. This stuff is driving me crazy
See above on how to use it. If you feel uncomfortable with it, the best is to follow the documentation, which recommend using a ForeignKey with unique=True in user profiles.
Also, do I need to use the sites app to do this stuff
From the site framework docs : Use it if your single Django installation powers more than one site and you need to differentiate between those sites in some way.
and finally does a "super user" have all permissions to everything (I don't want people from Account "Acme" to access account "Microshaft" objects)?
Again, from the docs, Designates that this user has all permissions without explicitly assigning them. That means that everywhere Django is using the built-in permission system (e.g. default administration pages), a super-user will be authorized.
In views you're writing yourself, or if you tweak some ModelAdmin, it's up to you to decide how you are going to check permissions.

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