Reputation: 315
The image attached displays my current problem. Math 270 and Math 280 in the picture were created by another user and not Jay, who created Jays course. However the other user is logged in currently, and not Jay. How can I get only the courses created by the logged in user, not Jay, to appear in that drop down menu?
In my views I have the following with attempts to solve the problem:
class CreateQuestion(LoginRequiredMixin, CreateView):
model = Question
fields = ["title", "question", 'classe']
template_name = "attendance_test/add_test.html"
def form_valid(self, form):
form.instance.instructor = self.request.user
return super(CreateQuestion, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(CreateQuestion, self).get_context_data(**kwargs)
context['classe'] = Classe.objects.filter(professor=self.request.user.id)
return context
def get_initial(self):
return { 'classe': Classe.objects.filter(professor=self.request.user.id) }
My Question model:
class Question(models.Model):
title = models.CharField(max_length=100)
question = models.TextField(max_length=500)
date_pub = models.DateTimeField(auto_now_add=True)
instructor = models.ForeignKey(Teacher, on_delete=models.CASCADE, default="")
# this is where all the courses are showing up, I only want those
# created by the "instructor" to show up, not all instructors
classe = models.ForeignKey(Classe, on_delete=models.CASCADE, null=True)
def professor_classes(self):
return Classe.objects.filter(professor=self.professor)
Teacher Model:
class Teacher(User):
isProfessor = models.BooleanField(default=False)
professor_courses = models.ForeignKey('Classe', on_delete=models.CASCADE, null=True)
This issue would be a problem if there were say as much as 1000 classes, but an instructor only thought 4, it would not make sense to display all 1000 when 996 had nothing to do with them. For the record I asked this question before, I got an answer but I was still not able to solve it.
Upvotes: 1
Views: 49
Reputation: 15836
There're many ways to solve this problem depending on how you structure your Django application. For example, one way could be:
class QuestionForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
professor = kwargs.pop('professor')
super(QuestionForm, self).__init__(*args, **kwargs)
self.fields['classe'].queryset = Classe.objects.filter(professor=professor)
class Meta:
model = Question
fields = ('title', 'question', 'classe')
class CreateQuestionView(LoginRequiredMixin, CreateView):
form = QuestionForm
template_name = "attendance_test/add_test.html"
def get_form_kwargs(self):
kwargs = super(CreateQuestionView, self).get_form_kwargs()
kwargs['professor'] = self.request.user
return kwargs
def form_valid(self, form):
form.instance.instructor = self.request.user
return super(CreateQuestionView, self).form_valid(form)
This filters classes based on the currently logged in user.
Although I think it is incorrect to inherit Teacher
model from User
. More performant and traditional solution would be to use aggregation in this case:
class Teacher(models.Model):
user = models.ForeignKey(User)
# or
#user = models.OneToOneField(User)
Also, you have problem with your code: initial
is an initial selected value for the form field, it's not a range of allowed values. By setting initial
you set an initial selected value for the form field.
context
is a dict of variables that are passed into your template. So I believe you don't need to define get_context
in your view (or at least it doesn't need to pass list of Classes
).
Upvotes: 1
Reputation: 27523
def get_form(self, form_class):
form = super(CreateQuestion, self).get_form(form_class)
form.fields['classe']= Classe.objects.filter(professor=self.request.user.id)
return form
you could try something like this
Upvotes: 1