I'm trying to use the Django REST framework to generate json I'll be able to use later on my website. The thing is, I have Users, who have one-to-many projects, and these projects have one-to-many tasks.
The thing is, I'd like to display a list of my users, then when I access the details of an user, I can see his projects. Then, when I check the details of a project, I can see the tasks of this project. Now, my models are defined like this :
class SimpleUser(AbstractBaseUser):
username = models.TextField(max_length=40, unique=True)
firstname = models.TextField(max_length=40)
lastname = models.TextField(max_length=40)
class Project(models.Model):
user = models.ForeignKey(SimpleUser, null=True)
name = models.TextField(max_length=255)
class Task(models.Model):
project = models.ForeignKey(Project, related_name='task_project')
title = models.TextField(max_length=255)
And when I'm trying to display for example the Projects linked to an User, I have an error no matter what I try (I'm pretty sure this is because what I do is wrong), and the error is "SimpleUser has no attribute Project". Which is logical. But I really don't know how to do this, can someone help me ?
You should use project_set to access SimpleUsers Projects.
user = SimpleUser.objects.get(id=1)
projects = user.project_set.all()
Or define a specific name for the manager with related_name=:
user = models.ForeignKey(SimpleUser, null=True, related_name='projects')
Then you can access users projects via projects:
projects = user.projects.all()
Try specifying explicitly the related_name for the relationship:
class Project(models.Model):
user = models.ForeignKey(SimpleUser, null=True, related_name='projects')
name = models.TextField(max_length=255)
Related
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.
I have a Django application where registered users can add, through an input form, details of performances of their music ensemble. This application also has a a section for composers, where they add their own composition. I'm using a custom user model, with profiles linked to user accounts:
class User(AbstractBaseUser):
email = models.EmailField(verbose_name="email", unique=True, max_length=255)
first_name = models.CharField(max_length=30, blank=True, null=True)
[...]
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
[...]
This is my 'composition' model:
class Composition(models.Model):
title = models.CharField(max_length=120) # max_length = required
composer = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
[...]
And this is my 'performance' model. The performance information links to the piece performed (performed):
class Performance(models.Model):
performed = models.ManyToManyField(Composition, blank=True)
[...]
So far, so good. Now, I'd like the performers to be able to add pieces by composers who are not (yet) registered to the website. Let's say that the performer performed a piece by John Lennon and is adding information about that performance. So, the performer will need to be able to add both John Lennon, his composition, and link the two.
The most important bit is: if the ghost of John Lennon tomorrow wants to register to the website, the administrator of the website will need to be able to easily link the compositions already added by the performers to John Lennon's newly created account. Is that possible? I suppose the key to solving this issue is changing composer = models.ForeignKey(settings.AUTH_USER_MODEL... with something else, i.e. using a intermediary model. Any suggestion will be greatly appreciated.
There are different ways to do this, you should choose one based on your taste:
When you know that the actual user is registered, just delete the old, fake user referred in the composition and replace it with the actual user.
Create a new model named something like Artist and change the composer relationship to refer to the Artist model. then, link the Artist model to the actual user with a nullable foreign key.
Let's say I've got 2 models
class Person(models.Model):
name = models.CharField(max_length=50)
class Language(models.Model):
person = models.ForeignKey(
Person, related_name='prs', on_delete=models.CASCADE)
name = models.CharField(max_length=50)
I want to be able to access all persons languages like that -> person/{person_id}/language
and to access and edit specific language like that -> person/{person_id}/language/{language_id}
In this scenario, you can use drf-nested-routers package.
As you are new to DRF, I know there is chance that you haven't seen routers and ModelViewSet yet, so I would recommend you to go through that first. Here is the link which explains this flow.
Just starting in Python/Django framework so sorry if this is dumb... but i cant find any solution.
class Dealer(models.Model):
name = models.CharField(max_length=200)
contacts = models.ManyToManyField(Contact)
class Contact(models.Model):
name = models.CharField(max_length=200)
dealers = models.ManyToManyField(Dealer)
I have this relation set up however when I run SyncDB it doesnt work. It tells me that Contact is not defined on this line
contacts = models.ManyToManyField(Contact)
Im more familiar with compiled languages. Is there anyway to tell python that the contact class exists, or better yet is there a special syntax im missing for defining this kind of relation.
I dont see a need for a two way ManyToMany in both the models, as they are a M:N relationship (2 way relationship).
Your issue here is, Contact is not defined at the point of execution of this code:
contacts = models.ManyToManyField(Contact)
So You need to wrap it in quotes for it to work
contacts = models.ManyToManyField('Contact')
Documentation on that can be found here
I would recommend the following models:
class Dealer(models.Model):
name = models.CharField(max_length=200)
contacts = models.ManyToManyField('Contact')
class Contact(models.Model):
name = models.CharField(max_length=200)
and It would do exactly what you are looking for.
You can read about ManyToMany relationships here. The same link also covers how to handle Reverse m2m queries
If you want to do a two way ManyToMany both, you just only need to do this:
class Dealer(models.Model):
name = models.CharField(max_length=200)
contacts = models.ManyToManyField('Contact', blank=True)
class Contact(models.Model):
name = models.CharField(max_length=200)
dealers = models.ManyToManyField('Dealer', through=Dealer.projects.through, blank=True)
I guess it will work to you.
I'm going to create some application with Django admin interface, with plugins in mind.
For example I have some user class in billing application:
class User(models.Model):
ContractNum = models.PositiveIntegerField(unique=True, blank=True, null=True )
LastName = models.CharField(max_length=50,)
and I have cmdb application, which has another model:
class Switch(models.Model):
Name = models.CharField(max_length=50, )
Manufacturer = models.CharField(max_length=50, )
Model = models.CharField(max_length=50, )
I would like to somehow virtually add to User model in billing application fields to have something like:
class User(models.Model):
ContractNum = models.PositiveIntegerField(unique=True, blank=True, null=True )
LastName = models.CharField(max_length=50,)
Switch = models.ForeignKey(Switch, related_name='SwitchUsers')
when I'm installed application cmdb, without any change in billing application dynamically.
I've read about abstract class, but I don't see the way how to achieve what I want with it, because it will add User into cmdb application, and I want something keep billing without changes as main application for the project.
Create a third model with has a OneToOne to User and a ForeignKey to Switch.