How to filter a django form's multiple choice or foreign key set with a generic view

On an app I am working on I needed to relate a photo to a project.

I created a model called Connection. It basically has two fields. "Photo" and "Project". They are both foreign keys back to the Photo and Project models.

Well I ran into a problem. I wanted to be able to say okay associate photo A with project B. I could do that and it would show a form with a drop down list of projects to associate a photo with. Problem was it was showing ALL users Projects.

I needed a way to filter the list of Projects in that list to ONLY the logged in user's project's. 

Also, I was currently using a generic view (CreateView) and since it was such a simple task wanted to keep using a generic view.

This is what I did on the view.


class AddPhotoToProject(CreateView):
    """
    a view where a user can associate a photo with a project
    """
    model = Connection
    form_class = CreateConnectionForm
    
    
    def get_context_data(self, **kwargs):
        context = super(AddPhotoToProject, self).get_context_data(**kwargs)
        context['photo'] = self.kwargs['pk']
        context['form'].fields['project'].queryset = Project.objects.for_user(self.request.user)
        return context
    def form_valid(self, form):
        pobj = Photo.objects.get(pk=self.kwargs['pk'])
        obj = form.save(commit=False)
        obj.photo = pobj
        obj.save()
        
        return_json = {'success': True}

        if self.request.is_ajax():

            final_response = json.dumps(return_json)
            return HttpResponse(final_response)
            
        else:

            messages.success(self.request, 'photo was added to project!')
            return HttpResponseRedirect(reverse('MyPhotos'))

The most important part is the

context['form'].fields['project'].queryset = Project.objects.for_user(self.request.user)

 

I used a manager to return only projects that hadn't been disabled and in that manager if defined 'for_user' that takes an argument (the user) and filters the list of projects.

Here is that Model Manager

class ProjectManager(models.Manager):
    def get_query_set(self):
        default_queryset = super(ProjectManager, self).get_query_set()
        return default_queryset.filter(disabled=None).order_by('-created_time')
    def for_user(self, user):
        return super(ProjectManager, self).get_query_set().filter(owner=user)