Reputation: 2197
I want to pass request.user or request.user.pk from class based view to the ModelForm in order to filter query set with request.user.pk . I have a following view:
class ArticleResurrectionView(MessageLoginRequiredMixin, FormView):
model = Article
form_class = ArticleResurrectionForm
template_name = "articles/resurrection.html"
success_url = reverse_lazy("articles:articles_main")
redirect_message = "You have to be logged in to recover articles "
def get_form_kwargs(self):
kwargs = FormView.get_form_kwargs(self)
kwargs["author_id"] = self.request.user.pk
return kwargs
def get_form_kwargs(self): should pass self.request.user.pk as a kwargs["author_id"] to form’s init
Then I have following form for this view:
class ArticleResurrectionForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.author_id = kwargs.pop("author_id", None)
forms.ModelForm.__init__(self, *args, **kwargs)
title = forms.ModelMultipleChoiceField(label="Deleted articles",
help_text="Please select the article to recover",
queryset=Article.default.filter(show=False, author=???) )
# I can not use self.author_id here
Target is to use self.author_id from init in the title to filter queryset in a such way to show entries only made by current user. In another words I need to pass self.author_id in the queryset in title.
Perhaps it is possible to do it by something like that:
def __init__(self, *args, **kwargs):
self.author_id = kwargs.pop("author_id", None)
forms.ModelForm.__init__(self, *args, **kwargs)
self.fields[“title"].queryset = ???
Anyway, if you know how to get request.user in the queryset – I would be happy to get your solution on that. Thank you!
p.s regarding Related managers: "default" instead of standard "objects", i use 2 managers:
class ArticleManager(models.Manager):
"""Shows only non deleted articles"""
def get_queryset(self):
return models.Manager.get_queryset(self).exclude(show=False)
class Article(models.Model):
# related managers
default = models.Manager() # shows all articles
objects = ArticleManager() # shows only non deleted articles
.....
.....
.....
Upvotes: 1
Views: 842
Reputation: 19
Add request.user to your form instance
form = FormItemForm(request.POST or None, request.user)
Then in your form.py add this
field = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
queryset=Field.objects.none(),
label='Fields',
help_text='Please select a field.'
)
def __init__(self, *args, **kwargs):
us = args[1] or None
forms.ModelForm.__init__(self, *args, **kwargs)
self.fields['field'].queryset = Field.objects.filter(user=us)
Try that and see if it works. it worked well for me.
Upvotes: 0
Reputation: 476594
Your second approach is indeed toe correct one, although you probably want to use a ModelChoiceField
[Django-doc] instead of a ModelMultipleChoiceField
[Django-doc], since the latter allows you to select multiple such Article
s, but your form logic (title
) hints that it is singular.
class ArticleResurrectionForm(forms.ModelForm):
title = forms.ModelChoiceField(
queryset=Article.objects.none()
label='Deleted articles',
help_text='Please select the article to recover'
)
def __init__(self, *args, **kwargs):
author_id = kwargs.pop("author_id", None)
forms.ModelForm.__init__(self, *args, **kwargs)
self.fields['title'].queryset = Article.objects.filter(
author_id=author_id,
show=False
)
We initially thus specify the queryset to be empty, but later patch that by specifying another queryset in the constructor of the form.
As for your view, you probably want to make a super()
call instead of calling the method of a specific class, like:
class ArticleResurrectionView(MessageLoginRequiredMixin, FormView):
# ...
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['author_id'] = self.request.user.pk
return kwargs
Upvotes: 1