I am really new to django, and I have some questions about how django's M2M works and also how it works with the modelForm or the forms.Form am currently working on an application that contains the following models:
class Agent(models.Model):
user = models.ForeignKey(User)
assigned_by = models.ForeignKey('self')
date = models.DateField(auto_now_add=True)
def __str__(self):
return str(self.user)
class Region(models.Model):
name = models.CharField(max_length=50)
# Agent to Region many-to-many
class ARM2M(models.Model):
agent = models.ForeignKey(Agent)
region = models.ForeignKey(Region)
is_manager = models.BooleanField(default=False)
Constraints:
an agent can be in multiple regions, and he/she can be one of the managers in any of those regions that he/she is in.
Question#1: is there a way to present such logic with the many-to-many feature in django model?
-end-of-question#1-
So I have this AgentForm for an agent manager to add an new agent in his/her regions. But I know this form is not working: because in the MultipleChoiceField, I have no way to get the current loggedin agent, to present the available regions. In other words, I am stuck.
class AgentForm(forms.Form):
agent = forms.IntegerField(widget=forms.HiddenInput())
regions = forms.MultipleChoiceField(choices=RAM2M.objects.filter(agent=agent, is_manager=True))
def save(self):
agent_id = self.cleaned_data['assigned_by']
agent = Agent.objects.get(pk=int(agent_id))
self.instance.assigned_by = agent
super(AgentForm, self).save()
class Meta:
model=Agent
exclude = ('assigned_by')
Question#2: How do I construct a form for an existing agent to add a new agent to the regions where he/she is a manager.
Thanks,
Maxim
Question #1: you can specify an intermediate model for the M2M relationship using the through argument:
class Agent(models.Model):
...
regions = models.ManyToManyField(Region, through='ARM2M')
(See http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany)
Regarding question #2, if think that this has the answer you're looking for: Creating a dynamic choice field
Related
Actually I'm creating an employee management system project using django rest api.
Now i have created my own custom models like shown below, i want to create the register employee with the below models. But how can i set the password field for login, since I haven't included in my fields. I've attached my models and serializer. Please do help for me. I'm beginner
Class Employee (models.Model):
name = models.CharField(max_length=50, unique=True, verbose_name='None')
email = models.EmailField(verbose_name='Email')
department = models.CharField(max_length=30, unique=False, verbose_name='Departamento')
(And many more details like personal email,contact, and many)
# Function used to display the employee's name in the admin page
def __str__(self):
return self.name
My serializer class is
class Employee DetailsSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
Fields = [__all__]
My views be like, i want to create register view, since i dont have password in my model, how to create password field to my above shown register field,
Whatever maybe my register field should contain all those above details. I'm scratching my head here.please someone help
Yes, you can add a password field in your Employee model but you are requested not to do it because Django already provided this type of facility. Just you have to know How to use it. Try to extend the existing User model from django.contrib.auth.models.User.Let's organize your Employee model.
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
#name = models.CharField(max_length=50, unique=True,
verbose_name='None')
#email = models.EmailField(verbose_name='Email')
department = models.CharField(max_length=30, unique=False,
verbose_name='Departamento')
#property
def name(self):
return "{0} {1}".format(self.user.first_name,
self.user.last_name)
No need to add an email field because this field already exists in the User model and the name field can be a property that retrieves data from the user model and the rest of the code will be unchanged. So you are concerned about the password field and it also exists in the User model.
Please check out this repo and it might help you.
I am working on developing a Trello-like website with Django Rest Framework.
I want to add selected users to BoardAccess model, a through table for User model and Board model, two of which are in Many to Many relationship. Being added to BoardAccess table will mean that the respective users will be having access to matching boards.
Models.py
class Board(models.Model):
name = models.CharField(max_length=50)
access_granted = models.ManyToManyField(User, through='BoardAccess', related_name='access_boards')
team = models.ForeignKey(Team, on_delete=models.CASCADE) # a team can have many boards
class BoardAccess(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
board = models.ForeignKey('Board', on_delete=models.CASCADE)
For User, I am currently using Django's default Auth User model and extending it with a Profile model via OneToOne Field.
Serializers.py
class BoardAccessSerializer(serializers.ModelSerializer):
members = serializers.SerializerMethodField()
added_users = # ???
new_name = serializers.CharField(
write_only=True, required=False, source='name') # in case of requests for renaming the board
def get_members(self, instance):
members = User.objects.filter(profile__team=instance.team)
return UserBoardSerializer(members, many=True).data
I would like to know what field / relations / another serializer should be assigned to added_users, which I think should be write_only=True, in order to successfully de-serialize input from the client-side containing primary keys of selected users.
get_members() method is used to first display information of all team members, from which a client will select users to be added to the board.
Views.py
class BoardAccessRetrieveUpdateAPIView(generics.RetrieveUpdateAPIView):
serializer_class = BoardAccessSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
team_id = self.kwargs.get('team_id')
team = get_object_or_404(Team, id=team_id)
queryset = Board.objects.select_related(
'team').prefetch_related(
'access_granted').filter(team=team)
return queryset
I am new to DRF, so there may be a lot of points to be improved from the above. I would really appreciate every help!!
You can override the update method in your serializer, and get the user ids from the client side from initial_data
def update(self, instance, validated_data):
// do the actions on create
users = self.initial_data.get('users')
instance.access_granted.add(*users)
instance.save()
return instance
Also when using ModelSerializer have to add Meta class:
class BoardAccessSerializer(serializers.ModelSerializer):
class Meta:
model = Board
fields = "__all__"
I've decided to embark on the task of creating my own LMS in Django for a final project in my Advanced Python course, unfortunately, I have reached a wall in terms of progress.
I have two models.
Course model, consists of multiple members (ManyToMany field)
Profile model, consists of several courses (ForeignKey field)
My question is, how can I have the Profile model linked to multiple courses?
Here is my code so far:
class Course(models.Model):
name = models.CharField(max_length=20)
members = models.ManyToManyField(User, related_name=("Members"))
def __str__(self):
return str(self.name)
class Profile(models.Model):
role = models.CharField(max_length=1, choices=roles)
user = models.OneToOneField(User, on_delete=models.CASCADE)
courses = models.ForeignKey(Course)
USERNAME_FIELD = 'user'
REQUIRED_FIELDS = ['user', 'password', 'role']
def __str__(self):
return str(self.user)
#receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save
Foreign key relations allow multiple instances of this model to be associated with a single instance of the other model, i.e.
class Profile(models.Model):
...
courses = models.ForeignKey(Course)
only allows one Course to be associated with a given Profile (but multiple Profiles can be associated with a single Course). You may think of it like a parent > child relation where Course is a parent and Profiles are children.
If you need to associate multiple Courses to be associated with a Profile (and still be able to have multiple Profiles associated with a Course), you should use a ManyToMany relation, such as:
class Profile(models.Model):
...
courses = models.ManyToMany(Course)
This effectively creates a third, hidden table (called a through table) which links both sides:
This is an example of how that through table looks like. Note that you don't have to create this manually as normally there is no model (it is implicit) and the database table is automatically generated by Django:
class ProfileCourse(models.Model):
profile = models.ForeignKey(Profile)
course = models.ForeignKey(Profile)
So I have been searching all around the internet for a full example of how to user AbstractUser when u have at least 2 different models. Didn't find anything conclusive.. at least that would work on latest version of Django (2.0.1).
I have 2 models, teacher and student, and registration needs to be different. Besides username, email, name and surname, I need for example, for the student, to upload a profile picture, email, phone, student_ID. And for teacher, bio, academic title and website. Did I start good ? What is the right approach ?
class Profile(AbstractUser):
photo = models.ImageField(upload_to='students_images')
email = models.EmailField()
phone = models.CharField(max_length=15, )
class Student(Profile):
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')])
def __str__(self):
return self.name
class Teacher(Profile):
academic_title = models.CharField(max_length=30)
bio = models.TextField()
website = models.URLField(help_text="E.g.: https://www.example.com", blank=True)
Your goals can be accomplished using a 'Profile' pattern. You don't necessarily need to use a custom user model for this. But you need to have a single common model to for authentication; you can use the builtin django user for this or a custom class... Your Student and Teacher models should be OnetoOne relationships. This is the recommended solution per the documentation.
If you wish to store information related to User, you can use a OneToOneField to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.
In your case, you may do something like this:
class StudentProfile(models.Model):
user = models.OneToOneField('User', related_name='student_profile')
# additional fields for students
class TeacherProfile(models.Model):
user = models.OneToOneField('User', related_name='teacher_profile')
# additional fields for teachers
Then you can create your registration forms based on these profile models.
class StudentResistrationForm(forms.ModelForm):
class Meta:
model = StudentProfile
fields = (...)
class TeacherRegistrationForm(forms.ModelForm):
class Meta:
model = TeacherProfile
fields = (...)
You can create the user instance to which the profile is related to at the same time you create the profile. You might do this with formsets, for example.
add
class Meta:
abstract = True
to profile model
and change AbstractUser to models.Model
I am trying to build a friendship relation in my project by using django-friendship package. The problem is that I what to build the relationship between my User model and my own model called Organisation. But when I am trying to do this it turned out that django-friendship supports only relationship between two objects of the same type (for example of type User-User). I even tried to override the existing models in django-friendship in order to change the methods but without any success. At the moment I am on the stage that the friend request is sent from User to Organisation but I need to accept it and there is where I struggle.
friendship/models.py
class FriendshipRequest(models.Model):
""" Model to represent friendship requests """
from_user = models.ForeignKey(user_model, related_name='organisation_requests_sent')
to_user = models.ForeignKey(organisation_model, related_name='organisation_requests_received')
def accept(self):
""" Accept this friendship request """
relation1 = Friend.objects.create(
from_user=self.from_user,
to_user=self.to_user
)
relation2 = Friend.objects.create(
from_user=self.to_user,
to_user=self.from_user
)
friendship_request_accepted.send(
sender=self,
from_user=self.from_user,
to_user=self.to_user
)
class Friend(models.Model):
""" Model to represent Friendships """
to_user = models.ForeignKey(user_model, related_name='organisations')
from_user = models.ForeignKey(organisation_model, related_name='_unused_organisation_relation')
The problem is that when it creates relationship1 and relationship2 it crashes because to_user and from_user are in a relationship with different models. I would be really glad if you help me with the problem or recommend another way (without using django-friendship package) of doing it in order to fit my requirements.
https://github.com/Ry10p/django-Plugis/blob/master/courses/models.py
Line 52
Also the position of the Friend model must be before the FriendRequest model, since the FriendRequest model relies on Friend for a ForeignKey.
Example:
class Author():
name = models.CharField(max_length=100)
bio = models.TextField(max_length=100)
class Article():
author = models.ForeignKey(Author)
text = models.TextField(max_length=500)
publish_date = models.DateTimeField(null=True)