Django: Redirect to Detail View after Creation - django

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}))

Related

AttributeError: 'AnonymousUser' object has no attribute 'profile'

I have built a Django app and it worked well.
When I had run an another django app in a port(localhost:8000) and tried the app I built on the port, it says error like this.
AttributeError: 'AnonymousUser' object has no attribute 'profile'
Here is my code:
class DashboardView(auth_views.LoginView):
template_name = "dashboard/home.html"
verify_email_required = 'registration/verify_email_required.html'
form_class = ProfiledAuthenticationForm
def get(self, request, *args, **kwargs):
# context = {'form': self.form_class()}
context = self.get_context_data()
context['form'] = self.form_class()
if request.user.profile.is_verified:
return render(request, self.template_name, context)
else:
return render(request, self.verify_email_required, context)
Note: Initial when I built the app, it worked well, but for now it takes error. when user does not log in, the homepage was redirected to login page.
When I fixed like this, it runs well.
class DashboardView(auth_views.LoginView):
template_name = "dashboard/home.html"
verify_email_required = 'registration/verify_email_required.html'
form_class = ProfiledAuthenticationForm
def get(self, request, *args, **kwargs):
# context = {'form': self.form_class()}
context = self.get_context_data()
context['form'] = self.form_class()
if self.request.user.is_authenticated:
if request.user.profile.is_verified:
return render(request, self.template_name, context)
return render(request, self.verify_email_required, context)
return render(request, self.template_name, context)

Converting Form Function to a Class Based View in a Django Project

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})

converting CBV to FBV

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)

Django not saving forms data in database

I am getting forms success message in my html template but forms data not saving. here is my code:
views.py:
class BlogDetailsAccount(FormMixin,DetailView):
model = Blog
template_name = 'blog/my-account-blog-details.html'
form_class = CommentFrom
def get_success_url(self):
return reverse('blog:my-account-blog-details', kwargs={'slug': self.object.slug})
def get_context_data(self, **kwargs):
#my context data........
return data
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
messages.add_message(self.request, messages.INFO, 'Your Comment pending for admin approval')
return self.form_valid(form)
else:
messages.add_message(self.request, messages.INFO, 'Somethings Wrong. Please try again')
return self.form_invalid(form)
def form_valid(self, form):
return super(BlogDetailsAccount, self).form_valid(form)
my models.py:
class BlogComment(models.model):
.......#my models fields....
.............
post_save.connect(BlogComment.user_comment, sender=BlogComment) #using signals
A FormMixin does not save the data to the database. In case you need to save the form, you should save it in the form_valid method:
A form_mixin does not save the data to the database.
class BlogDetailsAccount(FormMixin,DetailView):
# …
def post(self, request, *args, **kwargs):
form = self.get_form() # ← first create a form
self.object = self.get_object() # ← then specify the object
if form.is_valid():
messages.add_message(self.request, messages.INFO, 'Your Comment pending for admin approval')
return self.form_valid(form)
else:
messages.add_message(self.request, messages.INFO, 'Somethings Wrong. Please try again')
return self.form_invalid(form)
def form_valid(self, form):
form.save()
return super().form_valid(form)
You should also likely fill in relevant data like the post where the comment appears and

AttributeError: 'TestimonyForm' object has no attribute 'save'

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)