0👍
✅
It appears I needed to get the current user (not just the request
) using the form class’s __init__
method. Below is the views.py
and forms.py
code that ended up working:
views.py
# all necessary import statements
class MemberDetailView(
LoginRequiredMixin, FormMixin,
generic.DetailView, ProcessFormView
):
"""View class for member profile page"""
model = User
context_object_name = 'user'
form_class = JoinCommunityForm
success_url = '#communities-card'
template_name = 'home/terpuser_detail.html'
def get_queryset(self, *args, **kwargs):
qs = super().get_queryset(*args, **kwargs)
if not self.request.user.is_superuser:
qs = qs.filter(pk=self.request.user.pk)
return qs
def get_context_data(self, **kwargs):
context = super().get_context_data(
**kwargs,
demo=get_object_or_404(Scenario.objects, scenario_id='demo'),
today=date.today(),
)
return context
def form_valid(self, form):
# this is where I put my code to create a new Community membership object
return super().form_valid(self, form)
forms.py
The line that ended up solving my problems is in the form class’s __init__
method: self.user = self.request.user
. Then, I call self.user
in the form class’s clean
method rather than self.request.user
from communities.models import Community, UserRoleWithinCommunity
class JoinCommunityForm(forms.Form):
pin = forms.RegexField(
'^[A-HJ-NP-Z1-9]$',
max_length=6,
label='',
widget=forms.TextInput(attrs={
'oninput': 'this.value = this.value.toUpperCase()'
}
)
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None) # instantiate request kwarg as Willem suggests
self.user = self.request.user # get user, this was key to resolving error
super(JoinCommunityForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super().clean()
pin = self.cleaned_data['pin']
test_join_code = f'{pin}'
if Community.objects.filter(join_code=test_join_code).exists():
# Make sure user is not already a member of the community
communityToJoin = Community.objects.get(join_code=test_join_code)
if UserRoleWithinCommunity.objects.filter(
community=communityToJoin,
user=self.user # here I call self.user instead of self.request.user
).exists():
raise forms.ValidationError("You're already a member
of that Community")
else:
return cleaned_data
else:
raise forms.ValidationError("Join code is incorrect")
1👍
The reason this did not work is because you constructed the form with JoinCommunityForm(request.POST)
, whereas Django’s FormMixin
will call get_form_kwargs()
and then pass these to the form, as we can see in the source code [GitHub]:
def get_form(self, form_class=None): """Return an instance of the form to be used in this view.""" if form_class is None: form_class = self.get_form_class() return form_class(**self.get_form_kwargs())
In your view you can however easily handle this with:
from django.views.generic.edit import FormMixin, ProcessFormView
class MemberDetailView(
LoginRequiredMixin, FormMixin, generic.DetailView, ProcessFormView
):
model = User
context_object_name = 'user'
form_class = JoinCommunityForm
template_name = '…' # template used in MemberDetailView
def form_valid(self, form):
# do something when the form is valid
return super().form_valid(self, form)
- [Answered ]-Django related model, create if does not exist?
- [Answered ]-How would I make Django form fields have children?
- [Answered ]-Replace ModelChoiceField with auto suggest textfield with same queryset
Source:stackexchange.com