django how should I create my multiple user - django

I have two different users, one requesting for repairs (Office) and the inspector/repairman which is (Technician). I was wondering if this is a good idea to make both officeid/techid in customUser like this or there's a better way
this is the values of both office and technician, We have hr/accounting for example then EMP-**
this is my full erd so far I might change somethings based on your recommendations
Edit: I also thinking of adding similar to this, incase I create like IT support requesting aircon maintenance from machine office or something
class User(AbstractUser):
is_student = models.BooleanField('student status', default=False)
is_teacher = models.BooleanField('teacher status', default=False)

How about inheriting user class?
from django.contrib.auth.models import AbstractUser
class Technican(AbstractUser):
techName = models.CharField(max_length=64, verbose_name=_('Name'))
class Office(AbstractUser):
name = models.CharField(max_length=64, verbose_name=_('Name'))
head = models.CharField(max_length=64, verbose_name=_('Head'))
Or if you have custom fields that are mutual for both user types, then create first your own base user class and inherit that to Technican and Office.

Related

How to structure User - Team - Project model Django (ManyToMany)

I'm hoping someone can give me a push in the right direction, at least conceptually. What I'm trying to achieve; a model where:
You have users, workstreams and projects;
Workstream should always be linked to a project (i.e. they exist "in" projects)
Users can be linked to a project without being a workstream;
Users can be in multiple teams and projects
I've read something about Models Managers before, should I use these?
Something else I'm struggling with is that users can/should be linked to projects directly or though a team, will this cause problems?
below some snippets from the models.py file
class User(models.Model):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True
)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Workstream(models.Model):
name = models.CharField(max_length=100)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
members = models.ManyToManyField(User) #Like this?
class Project(models.Model):
name = models.CharField(max_length=100)
members = models.ManyToManyField(User) #Like this?
Any help in the right directions will be greatly appreaciated!
It is not advisable to link users directly to a project if it is possible to link teams to the same project. It would be possible for a given user to be two times in a Project, as a individual user or as part of a team, and you would have to search for Users and Users inside Teams when looking for all Users linked to a Project, which is cumbersome. Or if a Workstream represents a task to be done inside a Project, it wouldn't make sense to have a User that is not inside a task to be done.
I don't know the specifics of your project, but maybe each User would join a Team that is already part of a Project. A User could join a Team and be the sole member.
class Workstream(models.Model):
name = models.CharField(max_length=100)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
members = models.ManyToManyField(User)
class Project(models.Model):
name = models.CharField(max_length=100)
An admin could assign a Team to a Project or a user that has a 'project leader' privilege could assign a Team to a Project.

Django restrict user access to related objects

I am writing an application which allows a user to authenticate and view objects only within their organisation. For a generic.ListView, I can restrict access with the code below:
models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
organisation = models.ForeignKey('Organisation', null=True, on_delete=models.CASCADE)
class Organisation(models.Model):
name = models.CharField(max_length=255, unique=True, null=False, verbose_name="Name")
views.py
class OrganisationList(LoginRequiredMixin, generic.ListView):
model = Organisation
def get_queryset(self):
return Organisation.objects.filter(id=self.request.user.organisation.id)
In addition to this view the user will access forms, an API and the django admin interface that require this restriction.
For example, user Brett belongs to Kids Incorporated. When he logs in to the admin panel he can currently also see ACME Corporation but should not be able to do so.
I have looked at ModelManager interface but I am not sure how to get the user request and override
Is there a way to run write one query for all views (DRY) that so that a user will only see their own organisation?
There is a way.
Install django-crequest package: https://github.com/Alir3z4/django-crequest#installing
Create a model.Manager within models.py and override the get_queryset method
models.py
...
from crequest.middleware import CrequestMiddleware
class UserOrganisationManager(models.Manager):
def get_queryset(self):
request = CrequestMiddleware.get_request()
return super().get_queryset().filter(id=request.user.organisation.id)
class Organisation(models.Model):
name = models.CharField(max_length=255,
unique=True, null=False, verbose_name="Name")
...
objects = UserOrganisationManager()
You should use groups and permissions for that, a group per organization. And only members of some group can read (the permission) objects within their organization group.
This will allow you to have more that one organization for a user or vice-versa. And of course no require any other dependency.

Django AUTHENTICATION AND AUTHORIZATION groups and permissions want to create verified users

Hi Djangonauts,
I am new to Django please forgive any silly mistake in logic or code.
Intro:
I am building a web app in which members can write posts on a topic and offer courses on that topic. Example A member can write a blog about doing a wheelie on a bicycle and offer courses on that.
What I want:
I want members who want to offer courses to be verified. Example: The member has to fill a form with their details like...
name, address, and photo ID. Plus pay a charge of $9.99 to get verified. After admin (I in this case) checks if everything is good I will approve them. and then they will be "Verified Members" and be able to offer courses
What I have so far: Right now members can offer courses as there is no verified clause
class Event(models.Model):
user = models.ForeignKey(User, related_name='seller')
post = models.ForeignKey(Post, related_name='course')
price = models.DecimalField(max_digits=6, decimal_places=2)
stock = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(35)])
date = models.DateField()
time_from = models.TimeField()
time_to = models.TimeField()
event_types = (
('1', 'Webinar'),
('2', 'Actual Meet'),
)
event_choice = models.CharField(max_length=1, choices=event_types)
def get_absolute_url(self):
return reverse('posts:single', kwargs={'username': self.user.username,
'slug': self.post.slug})
def __str__(self):
return 'Meet for ' + self.post.title
How I plan to do it: I was planning to add a group in Django's admin AUTHENTICATION AND AUTHORIZATION
Home › Authentication and Authorization › Groups › Add group
Name: Verified
Permissions: Chosen permissions
event| event| Can add event
event| event| Can change event
event| event| Can delete event
Now what do I do from here?: Have I done things right so far, How do I take it from here. Do I create a model called verified and add forms.py to have members verified. How do permissions come in the picture.
My monkey patch (not a part of the question, for #Ojas Kale )
class Contact(models.Model):
user_from = models.ForeignKey(User, related_name='supporter')
user_to = models.ForeignKey(User, related_name='leader')
def __str__(self):
return '{} follows {}'.format(self.user_from, self.user_to)
User.add_to_class('following',
models.ManyToManyField('self', through=Contact, related_name='followers', symmetrical=False))
One way to go about it is adding a is_verified column in the user. There are various ways for doing this. but extending from abstractUser is probably the most straightforward and suitable in your case, since the class django.contrib.auth.models.AbstractUser provides the full implementation of the default User as an abstract model.
in your app_name.models.py create user class like this.
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
is_verified = models.BooleanField(default=False)
in your settingps.py
AUTH_USER_MODEL = 'app_name.User'
notice how app_name is used.
Now you can add as many attributes as you want as well.
By defaul is_verified is set to False, As soon as admin approves (verifies) the user change it to True.
Hope this helps.

RuntimeError: Can't resolve dependencies Django Groups with Users

Now I had a problem
RuntimeError: Can't resolve dependencies while running tests and after long debugging We found that a forigen key relationship is the problem
Yet we need this relation in our app
I have to get an owner relation to Django Groups
The models like that:
class UserAccount(AbstractUser):
arabic_name = models.CharField(max_length=128, default='', blank=True)
parent = models.ForigenKey('self', null=True)
django.contrib.auth.models import Group
Group.add_to_class('owner', models.ForeignKey('users.UserAccount',
blank=True,
null=True,
related_name='groups_created'
))
As I need to define an owner to the groups as I have my specific hierarchy system for users so no one can see others groups
So what Can I do?
Update - Solution
class UserAccount(AbstractUser):
arabic_name = models.CharField(max_length=128, default='', blank=True)
hierarchy_id = models.PositiveIntegerField()
django.contrib.auth.models import Group
Group.add_to_class('hierarchy_id', models.PositiveIntegerField(null=True))
#script populate hierarchy
h_id=0
for user in users:
if user.is_parent:
then user.hierar...... = h_id
and so on.. I populated hierarchy ID instead of relation
Thanks
Actually I found you can do a circular dependency without your knowledge, in case you do a relation and migrate it then do the reverse relation after a while then migrate it , it will not clash but when both migrated instantly in tests for example it will clash. so I tried this solution and tested, after a year from asking the question, it is working well.
class UserAccount(AbstractUser):
arabic_name = models.CharField(max_length=128, default='', blank=True)
hierarchy_id = models.PositiveIntegerField()
django.contrib.auth.models import Group
Group.add_to_class('hierarchy_id', models.PositiveIntegerField(null=True))
#script populate hierarchy
h_id=0
for user in users:
if user.is_parent:
then user.hierar...... = h_id

Django Model Design

I've previously asked questions for this project, regarding the Django Admin, Inlines, Generics, etc. Thanks again to the people who contributed answers to those. For background, those questions are here:
Django - Designing Model Relationships - Admin interface and Inline
Django Generic Relations with Django Admin
However, I think I should probably review my model again, to make sure it's actually "correct". So the focus here is on database design, I guess.
We have a Django app with several objects - Users (who have a User Profile), Hospitals, Departments, Institutions (i.e. Education Institutions) - all of whom have multiple addresses (or no addresses). It's quite likely many of these will have multiple addresses.
It's also possible that multiple object may have the same address, but this is rare, and I'm happy to have duplication for those instances where it occurs.
Currently, the model is:
class Address(models.Model):
street_address = models.CharField(max_length=50)
suburb = models.CharField(max_length=20)
state = models.CharField(max_length=3, choices=AUSTRALIAN_STATES_CHOICES)
...
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
...
class Hospital(models.Model):
name = models.CharField(max_length=20)
address = generic.GenericRelation(Address)
...
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
address = generic.GenericRelation(Address)
...
Firstly - am I doing it right, with the FK field on each object that has address(es)?
Secondly, is there a better alternative to using Generic Relations for this case, where different objects all have addresses? In the other post, somebody mentioned using abstract classes - I thought of that, but there seems to be quite a bit of duplication there, since the addresses model is basically identical for all.
Also, we'll be heavily using the Django admin, so it has to work with that, preferrably also with address as inlines.(That's where I was hitting an issue - because I was using generic relationships, the Django admin was expecting something in the content_type and object_id fields, and was erroring out when those were empty, instead of giving some kind of lookup).
Cheers,
Victor
I think what you've done is more complicated than using some kind of subclassing (the base class can either be abstract or not).
class Addressable(models.Model):
... # common attributes to all addressable objects
class Hospital(Addressable):
name = models.CharField(max_length=20)
...
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
class Address(models.Model):
street_address = models.CharField(max_length=50)
suburb = models.CharField(max_length=20)
state = models.CharField(max_length=3, choices=AUSTRALIAN_STATES_CHOICES)
...
owner = models.ForeignKey(Addressable)
You should consider making the base class (Addressable) abstract, if you don't want a seperate table for it in your database.