How do I create two sign-up systems? - python

So I wanted to create 2 signup options on the website. For example a student and teacher login methods. I want the form or model to extend and save it to the sqlite3 db. For example, if a student signs up the database would store a field isteacher = False and vise versa.
Also once they login is there a way to display two different dashboards based on the user?
Is there any guide or link to show me how to build this step by step? I have spent close to 8 hours figuring this out and i'm very close to giving up. Thanks for your time.

You don't need two sign up forms for such a thing if the students and teachers use the same credentials (e.g. username/email and password). Just simply add a selector for users to identify themselves. If they are not going to use same credentials, create a base view for common fields, then create separate signup views inheriting from that base view.
You need to extend User to add extra fields such as is_teacher (though I recommend you use CharField with choices so that you can add extra types of users in the future), there is a couple of ways of doing this explained elaborately in Django documentation, in your case setting up a custom user model via AbstractUser seems the best as I predict you will be extending that model further.
You can use UserPassesTestMixin or user_passes_test decorator to conditionally alter views for different types of users.

Related

Django Multiple Auth Models

I am working on a project where I need to have 3 types of Users.
Admin
Vendor
Customer
I want to be having seperate Models for all three of them Vendor & Customers instead of having a type field in a common User Model.
My first approach to this problem was to define all models by sub-classing the AbstractUser model
# models.py
from django.contrib.auth.models import AbstractUser
class Customer(AbstractUser):
pass
class Vendor(AbstractUser):
pass
And add a custom Authentication backend to handle the authentication of users based on the request object.
# settings.py
AUTHENTICATION_BACKENDS = ['backends.CustomAuthBackend']
And my backends.py file will contain the logic to authenticate users and use different models for each one based on the request object.
# backends.py
from __future__ import print_function
class CustomAuthBackend(object):
def authenticate(self, request, username=None, password=None):
# authenticate user based on request object
def get_user(self, user_id):
# logic to get user
However this does not work and looks like i also need to specifiy the AUTH_USER_MODEL in settings.py which is used for authentication.
Is it possible at all.Does Django allow to authenticate from 3 different tables. How can I go ahead with this ? Is there any other approach to this and what should I change ?
I have done similar staff a couple days ago, you are in the right approach. But there are a few other things needed to change to make it work. I'll explain what I did to make it success.
First, you have to custom your own user model, and you have to do it in the first place before you make the migrations. And also in the model file define different userManagers to manager different type of users. Then in your settings file you have to set AUTH_USER_MODEL and AUTHENTICATION_BACKENDS, AUTH_USER_MODEL is the default user model django will use for authentication and you can only set to one user model, but for AUTHENTICATION_BACKENDS you can have multiple backends,it's a list and django will loop every option inside to authenticate. by default it use django.contrib.auth.backends.ModelBackend, you can add your own auth backends. Check this on how to make your own authentication backend:https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#writing-an-authentication-backend.
And depends on your application, you may also need to custom the serializer function and override some classes to make it work. In my own application, I was using DRF and JWT token to authenticate, so I also override some of the function which by default use the AUTH_USER_MODEL variable. In the end, I'm able to use admin model to login the admin page and use another custom user model to authenticate the application and get the JWT token. Anyway, always reference this page: https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#customizing-authentication-in-django. Hope this can help you in your application.
django.contrib.auth is designed to work with one UserModel. Depending on what you want to achieve there are different apporaches.
If you just want to store different kind of profile/meta data for the different types of user you might use multi table inheritance - in this case you might stick with the default user model.
When it comes to different permissions based on the user type you should not solve this using separate classes. Instead use groups. This approach is much more flexible. It can nearly always happen that one person should belong to more than one group of users. When you model this based on the user classes you are in trouble.

Is it possible to extend Django admin with views not related to the database tables content?

I work on a simple app with two basic models, Document and Word. The user uploads a document, and each word from the Document is extracted in a Word entry. The user should be able to view, add, edit and remove the documents and the words, so I thought it would be good to use Django admin. But also the user should be able to do something more with the words, usually in a group of two and some additional adjustable parameters (like calculating Dice similarity).
Is there a way I can do all this in a one-level application? Or I have to make every user admin user, and make an app with just the additional functionality?
You can create custom view in the ModelAdmin or even in the admin site so there is no need to create an additional app.

Should I use my own users table or use the admin generated one with django?

I created my own user table. I've been learning how to use the admin panel and I saw there's already a user table.
Should I use it or mine? (for example connection, member panel etc...)
If I should use it how to update it?
If I shouldn't what do I have to use it for?
Use the one django provides.
If you want extra fields on your user, create an extension to the user model.
It's really easy to do, you can just create your own model and make it inherit from the django.contrib.auth.User model, or you can also look here:
Extending the User model with custom fields in Django for more awesome answers of how people are doing this exact thing

Django: multiple accounts, with multiple users under each account, but account-specific data

Using Django 1.5 here. I have an application I've created that currently has one big set of data, for one "account" if you will. Meaning all the data in all the models in my application are available to all logged-in users. Now, I want to be able to allow more people to use my application but with their own set of data. So I need to separate users into different accounts with different sets of data for each account. There could potentially be one or multiple users that has access to each account. At this time I don't need different users within one account to have different levels of access though I do intend for one user to be the account "owner".
I know that to make this conversion, I of course need to add a field to every model with a foreign key to a new "account" model. But beyond that I'm a little foggy. This appears to be a square peg in the round hole of Django's auth system. So the question is, what is the best approach?
A few thoughts I had so far:
Simply filter each and every query by account
Wrap each and every view with a decorator, but with multiple models, do I have to create a different decorator for each model? Can I tell from within the decorator which model is being accessed?
Somehow make use of the Auth system's user_passes_test decorator, but again, different models.
Extend the auth system to include a request.account attribute
Create a new mixin for my views? What if I'm not using exclusively CBVs?
Different middleware?
I considered using a new group for each account and then filtering by group instead of a new account model but I predict that would be a poor fit in this situation, as it isn't using groups as they were intended.
This is less of a code question and more of a big-picture, best-practices question. How would you approach this?
What you request is not so exotic: This is called authority data - you seperate your users to authorities and each authority will have each own data. For instance, you may have a number of departments in an organization - the data of each department can be edited only by members of the same department. I have already written a blog post with a simple approach to that using django:
http://spapas.github.io/2013/11/05/django-authoritiy-data/
To recap the post, I propose just adding an Authority model for which your User will have a ForeignKey (each User will have a Profile).
Now, all your Models whose data will belong to specific Authorities will just contain a ForeignKey to Authority. To check for the permissions you could use CBVs - the django admin will only be available to the central Administrators that have access to all the data. I recommend against using the django permissions for authorization of Authority data. If you want read the post which is much more detailed and ask here any questions.

Filter a User list using a UserProfile field in Django Admin

I'm trying to filter the User list in Django using a UserProfile Field... I need to implement a queue system where new users are put in a queue until an Admin approves them.
I simply added a is_in_queue boolean field to my UserProfile model... However, when displaying the user list in my Admin area, I realized that you can't filter the list using a Model's foreign key field (in this case, a field of UserProfile)
Apparently, list_display items can be callables but list_filter can't, so I can list IF a user is in the queue without a problem, but the admin would have to scroll through the whole user list to spot which ones are in the queue which makes no sense... Filtering only users that are in the queue (using userprofile.in_queue) would be much more practical...
Finally, I thought about adding a custom view to my admin area that would list only the user in the queue, but that custom view does not show up on the Admin area Index page, and putting together a whole new AdminSite only for a new filtering option seems a bit over the top...
So basically to sum it up: Can I filter my User list based on a
UserProfile field? If not, can I add a custom view that's accessible
from the front page without having to create a completely new
AdminSite only for that?
Django 1.3 fixed that - list_filter now allows to span relations:
https://docs.djangoproject.com/en/1.3/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter
You may want to take a look in to using a custom manager for the admin_objects of your model.
class UserAdminManager(models.AdminManager):
"""
Custom manager for the User model.
"""
def get_query_set(self):
"""
Overwrites the get_query_set to only return Users in the queue.
"""
return super(UserAdminManager, self).get_query_set().filter(userprofile__queue=True)
By overwriting the get_query_set method you can filter the results. Then just assign this to the admin_objects property of your User model.
admin_objects = UserAdminManager()
Some of the property names in my example may be wrong, as I don't know your model setup, but hopefully you get the idea.
You can research this further by checking out the django docs and searching for "custom managers".
It sounds to me like the quickest and easiest option is to add a new admin view to your application, specifically for your custom user model. See the Django admin docs for details, though it sounds like you know how to use Admin already.
Once the admin page is specific to your model, all your custom fields will no longer be foreign keys. This would make filtering easy.

Categories