Djnago how to split users and customres - python

In my project (small online shop) I need to split registration for users and customers.
So the information what I found when somebody registered in django then his account stored in one table, in this table I can see admin user and staff and another registered accounts, and I can sse them all in admin on Users page. But I do not want ot put all accounts in one "basket". I need split them fro different tables.
For example superuser can create in admin area a new user (content manager) and provide him access/permission to manage admin area (create product etc.) - this users and super user will be on default User page. On the page Customers will be displaying only users who registered for example via https://mysite/account/register page, after registration this customer account I can see in Customers page in the admin area but not in Users page. And this customer can login to his account for example via https://mysite/account/login
Is this possible?

As Jay said, everyone registered in the database is still a User whatever their role may be (admin, superuser, customer). What you could do is create a Profile model where everyone will have their information such as telephone, location etc, and you will also add another field clarifying their property.
PACKAGES = [
('customer', 'Customer'),
('support', 'Support'),
('admin', 'Admin'),
]
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
image = models.ImageField(default='user_avatar.png', upload_to='...')
last_visit = models.DateField(default=timezone.now, blank=True)
location = models.CharField(max_length=254, null=True, blank=True)
contact_phone = models.CharField(max_length=15)
user_role = models.CharField(default="customer", choices=PACKAGES, max_length=20)
Then all you need to do is edit your admin.py to implement a search parameter there:
class ProfileAdmin(admin.ModelAdmin):
list_filter=('user_role',)
admin.site.register(Profile, ProfileAdmin)
Doing that will give you a filter_list in the right corner of your admin page but that is for admin page only.
If you want to access different roles in your views or your templates you will do so by getting the user_role you need:
customers = Profile.objects.filter(user_role='customer')

Related

Django Multiple-User Model

I need advice on a multiple user type.
Scenario:
A user can be an organization, where in this organization they can place adverts on the website. The owner of this organization(user) can edit/delete users and adverts of his own organization(group). In this organization user type there are users that also can log in and they can only see the adverts placed by them, but the owner of this group must see all adverts of his own and of his users. Think like an estate listing where an organization has multiple locations/users that can place adverts, and has to be managed by a admin user of this organization.
What type or model is the best/cleanest for implementing this in a good way? Do I need the Django's User and Group model?
One solution would be to have the "User Profiles" structure.
So you use the standard Django User Model and you attach to it several OneToOne relationships depending on the number of profile types you'll have. This has the advantage of allowing users to cover more than one role at the same time.
For example:
from django.contrib.auth.models import User
class Organization(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="organization")
name = models.CharField(max_length=50, blank=True, null=True)
class Supervisor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="supervisor")
name = models.CharField(max_length=50, blank=True, null=True)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name="supervisors")
class CustomUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="custom_user")
name = models.CharField(max_length=50, blank=True, null=True)
supervisor = models.ForeignKey(Supervisor, on_delete=models.CASCADE, related_name="custom_users", blank=True, null=True)
And then when you go and create the models for the ads to be displayed on the website you can use the built-in PermissionRequiredMixin.
In order to do that you have to start by adding "permissions" in the ad model Meta class:
class Ad(models.Model):
# fields
class Meta:
permissions = [
('can_edit_ads', 'org_representative')
]
Then on your view you have to extend the PermissionRequiredMixin, example:
class EditAd(UpdateView, PermissionRequiredMixin):
model = Ad
template_name = "ad123.html"
permission_required = "ad.can_edit_ads"
A quick way to test it is by going in the user table on the admin panel, open a user detail page where you can see all the permissions, and there alongside the others you'll find your custom one as well.
From there you can easily assign the new permission to the specific user.

Django - What is the best approach to handle multiple user types...and route the HTML pages based on this?

I'm making a small test project with below user types: School Admin, Teacher, Student, Parent.
And each user type will have different Permissions like School Admin has full access... Parents can only view their Childern's Activity. Teacher can see all students but can add / edit marks for their respective students only. Teachers can setup Exam etc.. Students can take exam and submit the exam, but cannot edit / add any other information. Just can edit his profile detail.
Approach 1: Do i need to create a Custom User calss and apply to each user type (ie one Custome Class.. and 4 user type calss).. and similarly have 4 different view and html pages?
Approach 2: Just have one custome class and have an field with UserType which will have the have as "SchoolAdmin", "Teacher", "Student","Parent".. and one view and html (as the data page would remain same and only data record will restrict), and somehow identify the User Type in View, and filter the record?
Definately some view or html pages will be specific to one user type only which is i am able to handle, the issue is to use same view / html page to handle all user type.
Please suggest... and any code snippet will will more helpful.
# models.py
---------------------
class CustomUser(AbstractUser):
USER_TYPE_CHOICES = (
('SchoolAdmin'),
('Teacher'),
('Student'),
('Parents'),
)
user_type = models.CharField(blank=False, choices=USER_TYPE_CHOICES)
name = models.CharField(blank=False, max_length=255)
country = models.CharField(blank=False, max_length=255)
city = models.CharField(blank=False, max_length=255)
phone = models.CharField(blank=True, max_length=255)
created_at = models.DateField(auto_now_add=True)
def __str__(self):
return self.name
class SchoolAdmin(models.Model):
user = models.OneToOneField(
CustomUser, on_delete=models.CASCADE, primary_key=True)
class Teacher(models.Model):
user = models.OneToOneField(
CustomUser, on_delete=models.CASCADE, primary_key=True)
photo = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
class Student(models.Model):
user = models.OneToOneField(
CustomUser, on_delete=models.CASCADE, primary_key=True)
teacher = models.ForeignKey(Teacher)
photo = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
class Parent(models.Model):
user = models.OneToOneField(
CustomUser, on_delete=models.CASCADE, primary_key=True)
student= models.ForeignKey(Student)
Your CustomUser class is essentially correct. You don't really need the other classes (SchoolAdmin, Teacher, Student, Parent) as that functionality is described by user_type.
You do need to change the user type choices, something like:
SCHOOL, TEACHER, STUDENT, PARENT = 'school', 'teacher', 'student', 'parent'
USER_TYPES: (
(SCHOOL, 'School'),
(TEACHER, 'Teacher'),
(STUDENT, 'Student'),
(PARENT, 'Parent'),
)
The photo field can be added to the CustomUser class.
Furthermore, you will want to familiarize yourself with Django's documentation on custom authentication and permissions and authorization.
You can then create groups and permissions and assign your users to those. Teachers are a group with specific permissions, etc.
Also you can differentiate by user_type in your templates and views, to show or hide information, or access. For example:
def exam_setup_view(request):
# only teachers allowed here, others see 404
if request.user.user_type != CustomUser.TEACHER:
raise Http404()
EDIT This article explains how to use Django's groups and permissions. For example, you can create custom permissions on your User's Meta class, like so:
class CustomUser(AbstractUser):
# ...
class Meta:
permissions = (
("can_create_exam", "Can create exam"),
("can_view_user", "Can view user"),
)
That will create those custom permissions. You can assign those to users in Django's Admin, or programmatically, as further explained in that article or Django's documentation.
There are several ways of testing if a user has those permissions, ie: use the permission_required decorator, or when you have a user instance in your view: user.has_perm('appname.can_create_exam'), or from a template: {% if perms.appname.can_create_exam %}.

django models database schema

In Django, how would a database schema look like for a social media site like Instagram? For example, how would you make it so that one user can post multiple posts, and they can only have 1 profile?
I want to know what different tables I should have
I want to know how I would connect the tables
I want to know what I should write to link profile to posts(i.e. Foreign Key)
Any help is appreciated.
for profiles you add the user as a OneToOneField :
class Profile(models.model):
User=models.OneToOneField ()
Phone = models.CharField(default='', max_length=20)
Zip_code=models.IntegerField(default='')
image = models.ImageField(blank=True,upload_to='users_photos',)
and for post you add the user as a foreign key:
class Post(models.Model):
User=models.ForeignKey(
User,
on_delete=models.CASCADE,
)
....and some other fields you want to add

Automatically populate relations in Django admin

I'm working on my first Django app. My goal is to have two models, one for offices and one for employees, and when a person record is created (in the admin site), creating and specifying the room also populates that room with that person.
I was able to create the models, but now I'm stuck in a catch-22 where when I add a person, I have to create a room, but to create a room I have to add a person, etc...
How can I create and automatically populate a room like this?
Here is the relevant code from models.py:
class Room(models.Model):
number = models.CharField('Room number', primary_key=True, max_length=50)
occupant = models.ManyToManyField('Person', blank=True) # Can have multiple occupants
class Person(models.Model):
name = models.CharField('Full name', max_length=200)
office = models.ForeignKey(Room, on_delete=models.SET_NULL, null=True) # Some offices may not have an occupant
Update: I added blank=True to office so I can create an office with no occupant. But, even when I add a person and assign their office to that number, and it shows that in the admin page, the detail-view page doesn't seem to grab that, unless I manually go into the Room admin page and select the person. Can that part be automated?

Storing new field to Django Admin "user" section from registration form

I have managed to add an additional field to the Registration form, "where did you hear about us?".
But I am not sure which files to edit in order to store the data from this field along with the users info.
i.e. When logging into the Admin section and go to "users" and view a users info I would like to see this field there.
Simplest way would be to store additional data in a UserProfile model about the user, e.g.
from django.contrib.auth.models import User
class UserProfile(models.Model):
# This field is required.
user = models.OneToOneField(User)
# Other fields here
where_heard_about_us = models.TextField()
You can then register the object as an inline object in your Django Admin

Categories