Help needed. I have no idea what is error-ed in the line of code. The traceback points to the form.save() line.
#views.py
class TestimonyFormFunction(View):
form = TestimonyForm
template = 'variablized_form.html'
#method_decorator(login_required)
def get(self, request):
form = self.form_class(None)
return render(request, self.template, {'form':form})
def post(self, request):
if request.method == 'POST':
form = TestimonyForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return render(request, 'testimony_post.html', {'Testimony':Testimony})
else:
form = TestimonyForm()
return render(request, 'variablized_form.html', {'form': form})
#forms.py
class TestimonyForm(forms.Form):
body = forms.CharField(label='Details', widget=forms.Textarea)
Related
I am trying to convert my Form which is laid out in a function to be in a class based view:
Here is what I have reach out.
Function:
def add_business_plan(request):
info = Info.objects.all()
if request.method == 'POST':
form = infoForm(request.POST)
if form.is_valid():
form.save()
business_name = form.cleaned_data.get('businessName')
info_id = form.instance.id
messages.success(request, f'PDF created for {business_name}!, No.({info_id})')
return render(request, 'businessplan/businessplan.html', {'form': form, 'successful_submit': True})
else:
form = infoForm()
print(form.errors)
return render(request, 'businessplan/businessplan.html',
{
'form': form,
'successful_submit': False,
"Info": info
}
)
here is form
class infoForm(forms.ModelForm):
class Meta:
model = Info
fields = [
'businessName',
]
widgets = {
'problem_summary': RichTextFormField(),
}
You may try the following:
class AddBusinessPlan(View):
template_name = 'businessplan/businessplan.html'
form_class = infoForm
def get(self, request, *args, **kwargs):
form = self.form_class
print(form.errors)
return render(request, template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form.save()
business_name = form.cleaned_data.get('businessName')
info_id = form.instance.id
messages.success(request, f'PDF created for {business_name}!, No.({info_id})')
return render(request, self.template_name, {'form': form, 'successful_submit': True})
else:
return render(request, self.template_name, {'form': form})
I am trying to change all my Function Based View to Class based view, i’ve been fairly successful except for this view, it’s a detail view that contains paystack payment gateway. Any help will be hugely appreciated.
def car_rent_detail_view(request, pk):
object = get_object_or_404(CarRent, id=pk)
paystack = PaystackAccount(
settings.PAYSTACK_EMAIL,
settings.PAYSTACK_PUBLIC_KEY,
object.total_cost
)
context = {'object': object, 'pk_public': settings.PAYSTACK_PUBLIC_KEY, 'currency': 'NGN', 'paystack': paystack,
}
if request.method == 'POST':
if paystack.verify_transaction(request.POST['reference']):
messages.success(request, "payment successfull")
…
car_rented.save()
…
rent_activation.save()
messages.success(request, "Rent successfully updated")
return render(request, 'app/CarRent_detail.html', context=context)
I will like to convert the CBV below to FBV so i can add payment functionality to it.
class ContestantDetail(DetailView, FormMixin):
model = Contestant
context_object_name = 'contestants'
template_name = 'contest/contestant_detail.html'
form_class = VoteForm
def get_success_url(self):
return reverse('contest:contestant-detail', kwargs={'pk': self.object.pk})
def get_context_data(self, *args, **kwargs):
context = super(ContestantDetail, self).get_context_data(*args, **kwargs)
context['vote_contestant'] = Contestant.objects.get(pk=self.kwargs.get('pk'))
return context
def post(self, request, *args, **kwargs):
form = self.get_form()
self.object = self.get_object()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form, *args, **kwargs):
contestant = Contestant.objects.get(pk=self.kwargs['pk'])
...
contestant.save()
messages.success(self.request, f'You have successfully casted {vote_count} vote.')
return super().form_valid(form)
The Class based View above can be converted to a Function based view as demonstrated below.
def contestant_detail_view(request, pk):
get_object_or_404(Contestant, pk=pk)
form = VoteForm()
context = {'contestants': get_object_or_404(Contestant, pk=pk),
'vote_contestant': Contestant.objects.get(pk=pk),
'form': form}
if request.method == 'POST':
form = VoteForm(request.POST)
if form.is_valid():
con = Contestant.objects.get(pk=pk)
...
con.save()
else:
form = VoteForm()
return render(request, 'contest/contestant_detail.html', context)
I've come a cross a lot of tutorials regarding how to setup a class based view for ajax. Example:
class JoinFormView(FormView):
form_class = JoinForm
template_name = 'forms/ajax.html'
success_url = '/form-success/'
def form_valid(self, form):
response = super(JoinFormView, self).form_valid(form)
if self.request.is_ajax():
print(form.cleaned_data)
data = {
'message': "Successfully submitted form data."
}
return JsonResponse(data)
else:
return response
I'm wondering how would insert the required code for ajax into this function based view. Does the code required depend on whether or not I want to pull from or write to the db asynchronously?
def my_func_view(request):
template = 'accounts/profile.html'
form = Form123(request.POST or None)
if request.method == 'POST':
if form.is_valid():
instance = form.save(commit=True)
return redirect('/accounts/profile/')
else:
messages.error(request, 'There was an error.')
context = {'form': form,}
return render(request, template, context)
else:
context = {'form': form,}
return render(request, template, context)
Thanks for your help!
you do the same thing for the function based view too..
from django.http import JsonResponse
def my_func_view(request):
template = 'accounts/profile.html'
form = Form123(request.POST or None)
if request.is_ajax():
if form.is_valid():
instance = form.save(commit=True)
return JsonResponse({'status':'data'})
else:
messages.error(request, 'There was an error.')
return JsonResponse({'status':'data'})
else:
context = {'form': form,}
return render(request, template, context)
I'd like to redirect to a detail view after I successfully submitted a form and created the object.
My view.py
class ObjectCreateView(CreateView):
model = Object
form_class = ObjectCreateForm
template_name = 'frontend/base/object_create.html'
def get(self, request, *args, **kwargs):
form = ForecastConfigurationCreateForm()
form.fields['status'] = ModelChoiceField(queryset=ObjectStatus.get_object_status_list(self))
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
self.fcc_form = form.save(commit=True)
messages.add_message(self.request, messages.INFO, 'Good job!')
return render_to_response(reverse(viewname='object_detail', kwargs={'uuid': self.fcc_form.uuid}))
else:
messages.add_message(self.request, messages.ERROR, 'Error!')
return render(request, self.template_name, {'form': form})
The error message is:
TemplateDoesNotExist at /object_create/
/object_detail/3a3d6279-1531-45d4-9ba9-b691886facf4/
And the URL that's calling is:
http://test.com:8000/object_create/?next=/object_detail/a5b2a693-6f90-4b98-b9a2-fc2fe6a90995/
what I want it to be is
http://test.com:8000/object_detail/a5b2a693-6f90-4b98-b9a2-fc2fe6a90995/
Thanks!
Instead of trying to render the page, use HttpResponseRedirect instead:
class ObjectCreateView(CreateView):
...
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
self.fcc_form = form.save(commit=True)
messages.add_message(self.request, messages.INFO, 'Good job!')
return HttpResponseRedirect(reverse('object_detail', kwargs={'uuid': self.fcc_form.uuid}))
else:
messages.add_message(self.request, messages.ERROR, 'Error!')
return render(request, self.template_name, {'form': form})
just stumbled across the answer. The return should be:
return redirect(reverse('object_detail', kwargs={'uuid': self.fcc_form.uuid}))
I'm refactoring my code and change all FBVs to CBVs. But one of them isn't look pretty well. So I'm asking for right CBVs for my example.
Here my FBVs
#login_required
def profile(request, username):
user_main = get_object_or_404(User, username=username)
user_profile = UserProfile.objects.get_or_create(user=user_main)[0]
form = UserProfileForm({'website': user_profile.website, 'picture': user_profile.picture})
if request.method == 'POST' and request.user == user_main:
form = UserProfileForm(request.POST, request.FILES, instance=user_profile)
if form.is_valid():
form.save(commit=True)
return redirect(profile, username)
else:
print(form.errors)
context_dict = {'user_main': user_main, 'user_profile': user_profile, 'form': form}
return render(request, 'rango/profile.html', context=context_dict)
Here's what I'm got:
#method_decorator(login_required, name='dispatch')
class ProfileView(DetailView, FormMixin):
template_name = 'rango/profile.html'
context_object_name = 'user_main'
form_class = UserProfileForm
def get_object(self, queryset=None):
user_main = get_object_or_404(User, username=self.kwargs['username'])
return user_main
def get_context_data(self, **kwargs):
context = super(ProfileView, self).get_context_data(**kwargs)
context['user_profile'] = self.get_user_profile()
return context
def get_initial(self):
user_profile = self.get_user_profile()
return {'website': user_profile.website, 'picture': user_profile.picture}
def get_form_kwargs(self):
kwargs = super(ProfileView, self).get_form_kwargs()
kwargs['instance'] = self.get_user_profile()
return kwargs
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid and request.user == self.object:
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
profile = form.save(commit=True)
return redirect('profile', self.kwargs['username'])
def form_invalid(self, form):
print(form.errors)
return super(ProfileView, self).form_invalid(form)
def get_user_profile(self):
return UserProfile.objects.get_or_create(user=self.object)[0]
I guess my way to solve this task looks horrible. Please show me the right way to make this CBV looks better.