I'm making a project using the Django framework and is creating a website and is encountering this error:
Cannot assign "<User: >": "Booking.teacher" must be a "User" instance.
this is my model for User:
class User(AbstractUser):
groups = models.ManyToManyField(
'auth.Group',
related_name='custom_user_set', # Added related_name to avoid conflict
blank=True,
)
user_permissions = models.ManyToManyField(
'auth.Permission',
related_name='custom_user_permissions_set', # Added related_name to avoid conflict
blank=True,
)
ROLE_CHOICES = [
('admin', 'Admin'),
('teacher', 'Teacher'),
('student', 'Student'),
]
role = models.CharField(max_length=10, choices=ROLE_CHOICES)
this is my models.py for the booking:
class Booking(models.Model):
room = models.ForeignKey(Room, on_delete=models.CASCADE)
teacher = models.ForeignKey(User, on_delete=models.CASCADE, limit_choices_to={'role': 'teacher'})
date = models.DateField()
start_time = models.TimeField()
end_time = models.TimeField()
purpose = models.CharField(max_length=255, blank=True, null=True)
class Meta:
unique_together = ('room', 'date', 'start_time', 'end_time')
def __str__(self):
return f"{self.room.name} - {self.date} ({self.start_time} to {self.end_time})"
this is my forms.py:
class BookingForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['teacher'].queryset = User.objects.filter(groups__name='teacher') # Filter teachers
class Meta:
model = Booking
fields = ['room', 'date', 'start_time', 'end_time', 'teacher']
widgets = {
'date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
'start_time': forms.TimeInput(attrs={'type': 'time', 'class': 'form-control'}), # Updated to start_time
'end_time': forms.TimeInput(attrs={'type': 'time', 'class': 'form-control'}), # Added end_time
'room': forms.TextInput(attrs={'class': 'form-control'}),
'teacher': forms.Select(attrs={'class': 'form-control'}),
}
def clean(self):
cleaned_data = super().clean()
room = cleaned_data.get('room')
date = cleaned_data.get('date')
start_time = cleaned_data.get('start_time')
end_time = cleaned_data.get('end_time')
# Check for booking conflicts
if Booking.objects.filter(room=room, date=date, start_time=start_time, end_time=end_time).exists():
raise ValidationError('This room is already booked for the selected date and time.')
return cleaned_data
and this is my views:
def booking_calendar(request):
rooms = Room.objects.all() # Fetch all rooms for the dropdown
bookings = Booking.objects.all()
if request.method == 'POST':
form = BookingForm(request.POST)
if form.is_valid():
booking = form.save(commit=False)
booking.teacher = request.user if request.user.groups.filter(name='teacher').exists() else None # Assign the current user as the teacher if they are a teacher
if booking.teacher is None:
messages.error(request, 'You do not have permission to create a booking as a teacher.') # Error message
booking.save()
messages.success(request, 'Booking created successfully!')
return redirect('booking_calendar')
else:
messages.error(request, 'There was an error in your booking. Please check the form.')
else:
form = BookingForm()
return render(request, 'booking_calendar.html', {'bookings': bookings, 'form': form, 'rooms': rooms}) # Pass rooms to the template
I tested to see if the form works and reflects into the database in making a booking but there's only this error Cannot assign "<User: mhar>": "Booking.teacher" must be a "User" instance. I'm a beginner in this and is my first time seeing this error. I'm stuck in this error pls help
You did not install the customized User
model as the default user model, so request.user
is a django.contrib.auth.models.User
object, whereas teacher
is a my_app.models.User
model, and the two are thus in conflict.
You will need to set the AUTH_USER_MODEL
setting [Django-doc] to your user model, so:
# settings.py
# …
AUTH_USER_MODEL = 'my_app.User'
with my_app
the name of the app where you defined User
.
if Booking.objects.filter(room=room, date=date, start_time=start_time, end_time=end_time).exists():
This does not check all possible conflicts. For example if there is a booking between 10AM and 13PM, and you want to book the room between 11AM and 14PM, this will not raise any validation error. You need to check with:
if (
Booking.objects.exclude(pk=self.instance.pk)
.filter(
room=room, date=date, start_time__lt=end_time, end_time__gt=start_time
)
.exists()
):
pass
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation [Django-doc].