Django - Team/User relationships - python

I'm at a loss... I'm just learning Django and I am really rather confused about how to make a field work the way I would like it to.
I understand that Django has a native "Groups" model. However, I am looking to build my own teams model for customization and practice.
Here is my models.py file for my Users app:
from django.db import models
from django.contrib.auth.models import User
class Team(models.Model):
members = models.ManyToManyField(User)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
admin = models.BooleanField("Admin Status")
Here's where I'm confused. I would like to be able to call the team that the user is part of directly from User.Profile. So, I want to add a field to my Profile class that will automatically populate with the team name when a user is added to a team.
A potential problem I can see is that, currently, I can assign a user to multiple teams. This doesn't bother me, perhaps I can have a Profile model field that automatically populates with a list of all the teams that the user is associated with. Regardless, I can't figure out what type of field I would need to use, or how to do this.
Does that make sense?

A potential problem I can see is that, currently, I can assign a user to multiple teams.
Indeed, you can however easily retrieve the Teams the myprofile object is a member of with:
Team.objects.filter(members__profile=myprofile)
You thus can make a property for the Profile model:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
admin = models.BooleanField("Admin Status")
#property
def teams(self):
return Team.objects.filter(
members__profile=self
)
Then you thus access the Teams of a myprofile with myprofile.teams.

So, I want to add a field to my Profile class that will automatically populate with the team name when a user is added to a team.
From my limited knowledge of database, you can add a name field to your Team model.

Keeping in mind your requirement as mentioned in question, i would suggest you to use django reverse relations to get all the teams the profile is associated with
user_teams = User.objects.get(id='user_id').profile_set.all()[0].team_set.all()
to know more about django ORM reverse relation, here is a very short article

Related

Use new subclass with already in use database in django

I'm trying to create a customized User class inheriting from django User. Problem is I already have some users in database which can not be deleted whatsoever and also I have another class (let's say reports) which have a foreignkey to User. My question is: Is there any way to create my new User class and keep the old data too?
thanks in advance.
You can create related model that links back to User. This is a common approach if you have different types of users, but there are also other use cases.
class SpecialUserProfile(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.SET_NULL)
special_feature = models.CharField(max_length=100, null=True, blank=True)
etc.
What you also need to do is create this profile, when new user is added to User. You can do this with post_save signal.
#receiver(post_save, sender=User)
def create_special_user_profile(sender, instance, created, **kwargs):
if created:
SpecialUserProfile.objects.create(user=instance)
You create profiles for existing user with a command or write and run a temporary function that does that for existing users in User.
Now you can use ORM in the sense of user.specialuserprofile.special_feature.
This way you'll keep using User model as a base, it won't mess with build-in user related functionalities, won't have think about new and old users and you can use this new model for any additional information about users.

How Do I Create Special Fields For Users In Django

I'm new to Django and I want to create an app where artistes can post their songs and albums. Now I want artistes to have a different sign-up page from the normal users. I want artistes to be able to add their portraits, genres, and all that. Is there a way to add these fields to the User model? I've seen some questions on this but I don't think I really understood the answers.
There are basicly two ways to achive this:
1. Create a new model Artist with a OneToOneField to the django user model. This is most likely what you want. E.g. like this:
from django.contrib.auth.models import User
class Artist(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
genres = models.ManyToManyField('myapp.Genre', related_name='artists')
class Portrait(models.Model):
artist = models.ForeignKey('myapp.Artist', related_name='portraits')
class Genre(models.Model):
name = models.CharField(max_length=30)
2. Specify a custom User model that inherits from AbstractBaseUser. This is only reccomended if you want to store additional information related to authentication itself.
I suggest that you read the documentation on this carefully:
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#extending-the-existing-user-model
To create a custom sign-up page you will need to create your own FormView with a custom template e.g. using the django built in UserCreationForm and/or ModelForm. You could extend it with whichever fields you need. There are several ways to achive this depending on your needs.

Django setting up database for different users

I have Django project for recording personal expenses and keeping personal budget.
I have created required models for the project and authorization using Django. However the idea is that each authentic user shall keep own expenses records, therefore needs likely separate database. I have researched Django documentation and it seems doest not provide answer to this. Probably there is no need to set up another database but to create unique model fields inherited from default admin user fields and store the data for each user in the single database.
Please advice correct approach for this task.
You can always extend the auth user model to include additional data. You can create a new model that has all the additional fields plus a one-to-one relationship with the django user model.
eg:
from django.db import models
from django.conf import settings
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
date_of_birth = models.DateField(blank=True, null=True)
...
Here, you should be able to use the default auth user fields plus the custom fields you need.

Uncertain how to design django apps - best practices

In every django app I've previously developed I used only one app, which had all models, forms etc included.
It was OK for small apps, but now it's time to do it right way :)
I want to have auth module which will cover such things like user signups, login, welcome email sending etc.
So... I've created app called 'auth'. In auth.models module I have something like this:
class BaseModel(models.Model):
uuid = UUIDField()
time_created = models.DateTimeField(auto_now_add=True, null=True)
time_modified = models.DateTimeField(auto_now=True, null=True)
class Meta:
abstract = True
class Team(BaseModel):
title = models.CharField(_('Team title'), max_length=64)
class Member(BaseModel):
user = models.OneToOneField(User)
team = models.ForeignKey(Team)
USER_ROLES = (
('admin',_('Administrator')),
('member',_('Team member')),
)
role = models.CharField(_('User role'), max_length=6, choices=USER_ROLES, default='member')
Here comes my first trouble. Every user in my app will have one-to-one Member object. Member object stores some additional data about the user. Every single user must be assigned to group (which I call Team)... But wait... Should't be Team class moved to separated app which will manage Teams???
Also, I like to inherit all model classes from BaseModel. Do I have to add this same BaseModel class in every app again? Isn't a breaking "don't repeat yourself" rule?
Also, during registration of new user I need to create new Team for him. Where should I put code for this? Its related both to user management and team management.
I would need some guidance, how to fix these design issues.
Apps are intended to be self contained "modules" of code that could be reused in other django projects in the future. Ask yourself whether you'd ever want to re-use this code in another project.
Your extended user model, with teams would strike me as being part of a single app. You're not defining site-specific behaviour with respect to teams or members. I could also see many cases where you'd re-use the above code.

How to set up Django models with two types of users with very different attributes

Note: I've since asked this question again given the updates to Django's user model since version 1.5.
I'm rebuilding and making improvements to an already existing Django site and moving it over from Webfaction to Heroku, and from Amazon's SimpleDB to Heroku Postgres (though testing locally on Sqllite3 when developing). A lot of what I'm doing is moving over to use built-in Django functionality, like the Django admin, user authentication, etc.
Conceptually, the site has two kinds of users: Students and Businesses. The two types of users have completely different permissions and information stored about them. This is so much the case that in the original structure of the site, we set up the data model as follows:
Users
ID (primary_key)
Business_or_Student ('B' if business, 'S' if student)
email (unique)
password (hashed, obviously)
...
Students
ID (Foreignkey on Users)
<more information>
...
Businesses
ID (Foreignkey on Users)
<more information>
...
This worked pretty well for us, and we had the bare-bones user information in the Users table, and then any more detailed information in the Students and Businesses tables. Getting a user's full profile required something along this pseudocode:
def get_user_profile(id):
if Users(id=id).Business_or_Student = 'B':
return Businesses(id=id)
else:
return Students(id=id)
In moving over, I've found that Django's built-in User object has pretty limited functionality, and I've had to extend it with a UserProfile class I've created, and then had additional Student and Business tables. Given all of the patching I'm doing with this in the Django admin, and being relatively unfamiliar with Django models since I always did it differently, I'm not sure if this is the best way to go about it, or if I should just stick all of the information for businesses and students in the UserProfile table and just differentiate the two with different groups, or if there's even some way to do this all in the built-in User object.
Since businesses and students also have different interfaces, I'm seriously considering setting up the two as different apps within my Django project, and so separating their views, models, etc. entirely. That would look something like:
MyProject/
MyProject/ (project folder, Django 1.4)
mainsite/
students/
businesses/
One of my biggest concerns is with the Django Admin. In extending User, I already had to add the following code:
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'profile'
class UserAdmin(UserAdmin):
inlines = (UserProfileInline, )
However, I would like the information for the Business or Student aspects of the user to show up in the Django admin when that User is pulled up, but the ForeignKey part of the model is in the Student and Business model since every Student/Business has a User but every User has only one Student or one Business object connected with it. I'm not sure how to add a conditional Inline for the Admin.
Question: Given this structure and these concerns, what is the best way to set up this site, particularly the data model?
This is not a complete solution, but it will give you an idea of where to start.
Create a UserProfile model in mainsite. This will hold any common attributes for both types of users. Relate it to the User model with a OneToOne(...) field.
Create two more models in each app, (student/business), Business and Student, which have OneToOne relationships each with UserProfile (or inherit from UserProfile). This will hold attributes specific to that type of users. Docs: Multitable inheritance / OneToOne Relationships
You may add a field in UserProfile to distinguish whether it is a business or student's profile.
Then, for content management:
Define the save() functions to automatically check for conflicts (e.g. There is an entry for both Business and Student associated with a UserProfile, or no entries).
Define the __unicode__() representations where necessary.
I hope I understood your problem... maybe this can work? You create a abstract CommonInfo class that is inherited in into the different Sub-classes (student and businesses)
class CommonUser(models.Model):
user = models.OneToOne(User)
<any other common fields>
class Meta:
abstract = True
class Student(CommonUser):
<whatever>
class Business(CommonUser):
<whatever>
In this case the models will be created in the DB with the base class fields in each table. Thus when you are working with Students you run a
students = Students.objects.get.all()
to get all your students including the common information.
Then for each student you do:
for student in students:
print student.user.username
The same goes for Business objects.
To get the student using a user:
student = Student.objects.get(user=id)
The username will be unique thus when creating a new Student or Business it will raise an exception if an existing username is being saved.
Forgot to add the link

Categories