IndexError at /add_post/ list index out of range - python

I'm not sure why I'm getting this error, I recently put if and else method on my media file to catch some error and now I get a brand new one.
Here's my code.
media.py
import json
from goose import Goose
def extract(url):
g = Goose()
article = g.extract(url=url)
if article.top_image is None:
return "hello"
else:
resposne = {'image':article.top_image.src}
return article.top_image.src
views.py
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name = 'main/add_post.html'
def form_valid(self, form):
self.object = form.save(commit=False)
# any manual settings go here
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
#method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(PostCreateView, self).dispatch(request, *args, **kwargs)

Some of your top_image's might not have a src attribute defined. You could check like this:
def extract(url):
g = Goose()
article = g.extract(url=url)
if article.top_image is None:
return "hello"
else:
if article.top_image.src is None:
return "hello"
else:
resposne = {'image':article.top_image.src}
return article.top_image.src

Related

Changes to Django Template is not reflecting

I followed the instructions on https://github.com/tomwalker/django_quiz to use this project.
I am able to successfully use the project.
However, when I change the template (.html files) nothing changes. Even If I add or delete the entire content. I am not sure if I am missing something.
I checked in views.py and I cannot see any html renders. I am new to Django and finding it difficult to understand views.py and make any changes to the templates like questions or category. Any help would be greatly appreciated.
Interestingly if I make any changes to my original base.html the css and styles are applied as well as any other changes in base.html
urls.py code
urlpatterns = [
url(r'^$',
view=QuizListView.as_view(),
name='quiz_index'),
url(r'^category/$',
view=CategoriesListView.as_view(),
name='quiz_category_list_all'),
url(r'^category/(?P<category_name>[\w|\W-]+)/$',
view=ViewQuizListByCategory.as_view(),
name='quiz_category_list_matching'),
url(r'^progress/$',
view=QuizUserProgressView.as_view(),
name='quiz_progress'),
url(r'^marking/$',
view=QuizMarkingList.as_view(),
name='quiz_marking'),
url(r'^marking/(?P<pk>[\d.]+)/$',
view=QuizMarkingDetail.as_view(),
name='quiz_marking_detail'),
# passes variable 'quiz_name' to quiz_take view
url(r'^(?P<slug>[\w-]+)/$',
view=QuizDetailView.as_view(),
name='quiz_start_page'),
url(r'^(?P<quiz_name>[\w-]+)/take/$',
view=QuizTake.as_view(),
name='quiz_question'),
]
Views.py code
class QuizMarkerMixin(object):
#method_decorator(login_required)
#method_decorator(permission_required('quiz.view_sittings'))
def dispatch(self, *args, **kwargs):
return super(QuizMarkerMixin, self).dispatch(*args, **kwargs)
class SittingFilterTitleMixin(object):
def get_queryset(self):
queryset = super(SittingFilterTitleMixin, self).get_queryset()
quiz_filter = self.request.GET.get('quiz_filter')
if quiz_filter:
queryset = queryset.filter(quiz__title__icontains=quiz_filter)
return queryset
class QuizListView(ListView):
model = Quiz
def get_queryset(self):
queryset = super(QuizListView, self).get_queryset()
return queryset.filter(draft=False)
class QuizDetailView(DetailView):
model = Quiz
slug_field = 'url'
def get(self, request, *args, **kwargs):
self.object = self.get_object()
if self.object.draft and not request.user.has_perm('quiz.change_quiz'):
raise PermissionDenied
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
class CategoriesListView(ListView):
model = Category
class ViewQuizListByCategory(ListView):
model = Quiz
template_name = 'view_quiz_category.html'
def dispatch(self, request, *args, **kwargs):
self.category = get_object_or_404(
Category,
category=self.kwargs['category_name']
)
return super(ViewQuizListByCategory, self).\
dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(ViewQuizListByCategory, self)\
.get_context_data(**kwargs)
context['category'] = self.category
return context
def get_queryset(self):
queryset = super(ViewQuizListByCategory, self).get_queryset()
return queryset.filter(category=self.category, draft=False)
class QuizUserProgressView(TemplateView):
template_name = 'progress.html'
#method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(QuizUserProgressView, self)\
.dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(QuizUserProgressView, self).get_context_data(**kwargs)
progress, c = Progress.objects.get_or_create(user=self.request.user)
context['cat_scores'] = progress.list_all_cat_scores
context['exams'] = progress.show_exams()
return context
class QuizMarkingList(QuizMarkerMixin, SittingFilterTitleMixin, ListView):
model = Sitting
def get_queryset(self):
queryset = super(QuizMarkingList, self).get_queryset()\
.filter(complete=True)
user_filter = self.request.GET.get('user_filter')
if user_filter:
queryset = queryset.filter(user__username__icontains=user_filter)
return queryset
class QuizMarkingDetail(QuizMarkerMixin, DetailView):
model = Sitting
def post(self, request, *args, **kwargs):
sitting = self.get_object()
q_to_toggle = request.POST.get('qid', None)
if q_to_toggle:
q = Question.objects.get_subclass(id=int(q_to_toggle))
if int(q_to_toggle) in sitting.get_incorrect_questions:
sitting.remove_incorrect_question(q)
else:
sitting.add_incorrect_question(q)
return self.get(request)
def get_context_data(self, **kwargs):
context = super(QuizMarkingDetail, self).get_context_data(**kwargs)
context['questions'] =\
context['sitting'].get_questions(with_answers=True)
return context
class QuizTake(FormView):
form_class = QuestionForm
template_name = 'question.html'
result_template_name = 'result.html'
single_complete_template_name = 'single_complete.html'
def dispatch(self, request, *args, **kwargs):
self.quiz = get_object_or_404(Quiz, url=self.kwargs['quiz_name'])
if self.quiz.draft and not request.user.has_perm('quiz.change_quiz'):
raise PermissionDenied
try:
self.logged_in_user = self.request.user.is_authenticated()
except TypeError:
self.logged_in_user = self.request.user.is_authenticated
if self.logged_in_user:
self.sitting = Sitting.objects.user_sitting(request.user,
self.quiz)
else:
self.sitting = self.anon_load_sitting()
if self.sitting is False:
return render(request, self.single_complete_template_name)
return super(QuizTake, self).dispatch(request, *args, **kwargs)
def get_form(self, *args, **kwargs):
if self.logged_in_user:
self.question = self.sitting.get_first_question()
self.progress = self.sitting.progress()
else:
self.question = self.anon_next_question()
self.progress = self.anon_sitting_progress()
if self.question.__class__ is Essay_Question:
form_class = EssayForm
else:
form_class = self.form_class
return form_class(**self.get_form_kwargs())
def get_form_kwargs(self):
kwargs = super(QuizTake, self).get_form_kwargs()
return dict(kwargs, question=self.question)
def form_valid(self, form):
if self.logged_in_user:
self.form_valid_user(form)
if self.sitting.get_first_question() is False:
return self.final_result_user()
else:
self.form_valid_anon(form)
if not self.request.session[self.quiz.anon_q_list()]:
return self.final_result_anon()
self.request.POST = {}
return super(QuizTake, self).get(self, self.request)
def get_context_data(self, **kwargs):
context = super(QuizTake, self).get_context_data(**kwargs)
context['question'] = self.question
context['quiz'] = self.quiz
if hasattr(self, 'previous'):
context['previous'] = self.previous
if hasattr(self, 'progress'):
context['progress'] = self.progress
return context
def form_valid_user(self, form):
progress, c = Progress.objects.get_or_create(user=self.request.user)
guess = form.cleaned_data['answers']
is_correct = self.question.check_if_correct(guess)
if is_correct is True:
self.sitting.add_to_score(1)
progress.update_score(self.question, 1, 1)
else:
self.sitting.add_incorrect_question(self.question)
progress.update_score(self.question, 0, 1)
if self.quiz.answers_at_end is not True:
self.previous = {'previous_answer': guess,
'previous_outcome': is_correct,
'previous_question': self.question,
'answers': self.question.get_answers(),
'question_type': {self.question
.__class__.__name__: True}}
else:
self.previous = {}
self.sitting.add_user_answer(self.question, guess)
self.sitting.remove_first_question()
def final_result_user(self):
results = {
'quiz': self.quiz,
'score': self.sitting.get_current_score,
'max_score': self.sitting.get_max_score,
'percent': self.sitting.get_percent_correct,
'sitting': self.sitting,
'previous': self.previous,
}
self.sitting.mark_quiz_complete()
if self.quiz.answers_at_end:
results['questions'] =\
self.sitting.get_questions(with_answers=True)
results['incorrect_questions'] =\
self.sitting.get_incorrect_questions
if self.quiz.exam_paper is False:
self.sitting.delete()
return render(self.request, self.result_template_name, results)
def anon_load_sitting(self):
if self.quiz.single_attempt is True:
return False
if self.quiz.anon_q_list() in self.request.session:
return self.request.session[self.quiz.anon_q_list()]
else:
return self.new_anon_quiz_session()
def new_anon_quiz_session(self):
"""
Sets the session variables when starting a quiz for the first time
as a non signed-in user
"""
self.request.session.set_expiry(259200) # expires after 3 days
questions = self.quiz.get_questions()
question_list = [question.id for question in questions]
if self.quiz.random_order is True:
random.shuffle(question_list)
if self.quiz.max_questions and (self.quiz.max_questions
< len(question_list)):
question_list = question_list[:self.quiz.max_questions]
# session score for anon users
self.request.session[self.quiz.anon_score_id()] = 0
# session list of questions
self.request.session[self.quiz.anon_q_list()] = question_list
# session list of question order and incorrect questions
self.request.session[self.quiz.anon_q_data()] = dict(
incorrect_questions=[],
order=question_list,
)
return self.request.session[self.quiz.anon_q_list()]
def anon_next_question(self):
next_question_id = self.request.session[self.quiz.anon_q_list()][0]
return Question.objects.get_subclass(id=next_question_id)
def anon_sitting_progress(self):
total = len(self.request.session[self.quiz.anon_q_data()]['order'])
answered = total - len(self.request.session[self.quiz.anon_q_list()])
return (answered, total)
def form_valid_anon(self, form):
guess = form.cleaned_data['answers']
is_correct = self.question.check_if_correct(guess)
if is_correct:
self.request.session[self.quiz.anon_score_id()] += 1
anon_session_score(self.request.session, 1, 1)
else:
anon_session_score(self.request.session, 0, 1)
self.request\
.session[self.quiz.anon_q_data()]['incorrect_questions']\
.append(self.question.id)
self.previous = {}
if self.quiz.answers_at_end is not True:
self.previous = {'previous_answer': guess,
'previous_outcome': is_correct,
'previous_question': self.question,
'answers': self.question.get_answers(),
'question_type': {self.question
.__class__.__name__: True}}
self.request.session[self.quiz.anon_q_list()] =\
self.request.session[self.quiz.anon_q_list()][1:]
def final_result_anon(self):
score = self.request.session[self.quiz.anon_score_id()]
q_order = self.request.session[self.quiz.anon_q_data()]['order']
max_score = len(q_order)
percent = int(round((float(score) / max_score) * 100))
session, session_possible = anon_session_score(self.request.session)
if score is 0:
score = "0"
results = {
'score': score,
'max_score': max_score,
'percent': percent,
'session': session,
'possible': session_possible
}
del self.request.session[self.quiz.anon_q_list()]
if self.quiz.answers_at_end:
results['questions'] = sorted(
self.quiz.question_set.filter(id__in=q_order)
.select_subclasses(),
key=lambda q: q_order.index(q.id))
results['incorrect_questions'] = (
self.request
.session[self.quiz.anon_q_data()]['incorrect_questions'])
else:
results['previous'] = self.previous
del self.request.session[self.quiz.anon_q_data()]
return render(self.request, 'result.html', results)
def anon_session_score(session, to_add=0, possible=0):
"""
Returns the session score for non-signed in users.
If number passed in then add this to the running total and
return session score.
examples:
anon_session_score(1, 1) will add 1 out of a possible 1
anon_session_score(0, 2) will add 0 out of a possible 2
x, y = anon_session_score() will return the session score
without modification
Left this as an individual function for unit testing
"""
if "session_score" not in session:
session["session_score"], session["session_score_possible"] = 0, 0
if possible > 0:
session["session_score"] += to_add
session["session_score_possible"] += possible
return session["session_score"], session["session_score_possible"]
When I make changes to etbox/templates/base.html , my changes are reflected in all the Quiz Html(s).
This is how your links and templates should link up:
You first create a url address in your apps directory folder in file called urls.py:
"""Defines the URL patterns for app created within django"""
from django.conf.urls import url
from . import views
urlpatterns = [
# Home page
url(r'^$', views.index, name='index'),#notice how I mention the function called index within the views.py file
...
]
Then you add a function within the same folder as your urls.py that allows to carry information from your models and forms into your templates (but that is optional).
def index(request):
"""Creating a homepage view"""
return render(request, '#app_name/index.html')
When creating an .html file remember that it's supposed to located in a specific location for django to read it. This is most likely your problem. Your .html file isn't in the right location for django to render it.
This is the general file path from your main project directory for the .html file. #main_directory/#django_app_directory/#templates/#django_app_name_folder/.html_file
. So basically the .html file has to be located in a folder called templates within the same directory as your views.py and urls.py. Inside the templates folder you make another folder that is called the same as your app name folder. Within this app name folder you can put your .html file.
I just had a quick look at it and it seems in views.py that he's using just generic views, that's why he never calls the render function directly.
So, as you can see in urls.py, the home page is associated with QuizListView from views.py QuizListView inherits from django.views.generic.ListView
If you look at the documentation, you will see that the default template name for that is the name of the model you specify + '_list'
class QuizListView(ListView):
model = Quiz
def get_queryset(self):
queryset = super(QuizListView, self).get_queryset()
return queryset.filter(draft=False)
This template is in this path: django_quiz/quiz/templates/quiz/quiz_list.html
Edit it and the changes should reflect in the browser when you refresh the page

How can i get the pk from a cloned model instance in form_valid to use in get_success_url in an UpdateView?

class DomainRegistrationItemUpdateView(UpdateView):
model = DomainRegistrationItem
form_class = DomainAddYearsForm
template_name = "add_years.html"
def get_context_data(self, *args, **kwargs):
context = super(DomainRegistrationItemUpdateView,
self).get_context_data(**kwargs)
# tld_ppy Top Level Domain Price Per Year
context['tld_ppy'] = TLD.objects.get(
name='.%s' % (self.kwargs['domain_name'].split('.')[1])).yearly_price
return context
def get_object(self, queryset=None):
return DomainRegistrationItem.objects.get(domain=self.kwargs['domain_name'], purchased=True)
def get_success_url(self):
split_dn = self.kwargs['domain_name'].split('.')
namespace = split_dn[0]
sld = split_dn[1]
return reverse("domain_registraiton_item_detail", kwargs={
"pk": self.kwargs['pk'],
'namespace': namespace,
'second_level_domain': sld})
def form_valid(self, form):
f = form.save(commit=False)
working_dri = DomainRegistrationItem.objects.get(domain=self.kwargs['domain_name'])
working_dri.pk = None
working_dri.save()
working_dri.purchased = False
working_dri.years = f.years
f.save()
return super(DomainRegistrationItemUpdateView, self).form_valid(form)
The working_dri code is code that clones a DomainRegistrationItem under consideration by the view.
I want to get the pk from working_dri to usee in get_success_url. How can I do this? Thanks in advance for any and all help.
An UpdateView stores the object it saves to self.object, as we can see in the source code:
def form_valid(self, form):
"""If the form is valid, save the associated model."""
self.object = form.save()
return super().form_valid(form)
so we can make use of:
class DomainRegistrationItemUpdateView(UpdateView):
model = DomainRegistrationItem
form_class = DomainAddYearsForm
template_name = "add_years.html"
# …
def get_success_url(self):
split_dn = self.kwargs['domain_name'].split('.')
namespace = split_dn[0]
sld = split_dn[1]
return reverse("domain_registraiton_item_detail", kwargs={
"pk": self.object.pk,
'namespace': namespace,
'second_level_domain': sld})
def form_valid(self, form):
form.instance.pk = None
form.instance.purchased = False
form.instance.years = f.years
return super(DomainRegistrationItemUpdateView, self).form_valid(form)

HttpResponseRedirect not working in django

HttpResponseRedirect not working it shows error as 'context must be dict rather than response'
class FooterLinksView(TemplateView):
template_name = 'pages/footerlinks.html'
model = FooterLink
def get_context_data(self, **kwargs):
context = super(FooterLinksView,self).get_context_data(**kwargs)
string_name = self.kwargs['string']
obj = FooterLink.objects.get(link_url=string_name)
if obj.link_type == 'page':
try:
context['page_obj'] = obj
return context
except:
pass
else:
pass
print(obj.url_name)
return HttpResponseRedirect(str(obj.url_name))
get_context_data() is the method for return context, so it must return context object. If you want to redirect, do it in get().
like below
class FooterLinksView(TemplateView):
template_name = 'pages/footerlinks.html'
model = FooterLink
def get(self, request, *args, **kwargs):
string_name = self.kwargs['string']
obj = FooterLink.objects.get(link_url=string_name)
if obj.link_type != 'page':
return HttpResponseRedirect(str(obj.url_name))
else:
return super().get(*args, **kwargs)
# if python2
# return super(FooterLinksView, self).get(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super(FooterLinksView,self).get_context_data(**kwargs)
string_name = self.kwargs['string']
obj = FooterLink.objects.get(link_url=string_name)
if obj.link_type == 'page':
try:
context['page_obj'] = obj
return context
except:
pass
return context
or you can just use extra_context in TemplateView.
class FooterLinksView(TemplateView):
template_name = 'pages/footerlinks.html'
model = FooterLink
def get(self, request, *args, **kwargs):
string_name = self.kwargs['string']
obj = FooterLink.objects.get(link_url=string_name)
if obj.link_type != 'page':
try:
self.extra_context = {
'page_obj': obj
}
except:
pass
return HttpResponseRedirect(str(obj.url_name))
else:
return super().get(*args, **kwargs)
# if python2
# return super(FooterLinksView, self).get(*args, **kwargs)
You must always return a dict from your get_context_data function. If you want to redirect, you should override dispatch too:
class FooterLinksView(TemplateView):
...
def dispatch(self, request, *args, **kwargs):
string_name = self.kwargs['string']
obj = FooterLink.objects.get(link_url=string_name)
if obj.link_type != 'page':
return HttpResponseRedirect(str(obj.url_name))
return super(FooterLinksView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(FooterLinksView,self).get_context_data(**kwargs)
string_name = self.kwargs['string']
obj = FooterLink.objects.get(link_url=string_name)
context['page_obj'] = obj
return context
The code in your get_context_data is trying to retrieve a single object and passing it to the context dictionary. This functionality is already built-in the DetailView and seems to be a better fit here than the TemplateView.
from django.views.generic import DetailView
class FooterLinksView(DetailView):
model = FooterLink
template_name = 'pages/footerlinks.html'
def get(self, request, *args, **kwargs):
self.object = self.get_object()
if self.object.link_type == 'page':
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
return HttpResponseRedirect(str(obj.url_name))
Now the only thing we need to add is how the FooterLink object is retrieved in the get_object method. If your link_url field of FooterLink is the primary key we can simply add pk_url_kwarg = 'link_url' in the top of the class. Otherwise you should use the slug_field and slug_url_kwarg.
class FooterLinksView(DetailView):
model = FooterLink
pk = 'link_url' # if link_url is the primary key
slug_field = 'link_url' # if link_url is not the primary key
slug_url_kwarg = 'string' # if link_url is not the primary key
template_name = 'pages/footerlinks.html'
...
Note: You should now use the object variable inside your template (instead of obj) or override yet another option: context_object_name.
class FooterLinksView(TemplateView):
template_name = 'pages/footerlinks.html'
model = FooterLink
def get(self, request, args, *kwargs):
context = self.get_context_data(**kwargs)
string_name = self.kwargs['string']
obj = get_object_or_404(FooterLink, link_url=string_name)
if obj.link_type == 'page':
context['page_obj'] = obj
return render(request, self.template_name, context)
else:
a = obj.url_name
return HttpResponseRedirect(a)

'NoneType' object has no attribute 'strip'-extract image from posted url

Error is occuring from media.py, it looks like my url is none. but I don't understand why. how do I set url equals to the posted url from a user? If you see my views.py, I tried to set it like that. url equals to self.request.GET.get('url'). Did I do it wrong?
media.py
import json
import urllib2
from urllib2 import Request
from goose import Goose
def get_content(url):
"""This function is intended to return content from url.
:param url: URL to get content
:return: The response from url
"""
req = urllib2.Request(url, headers={'User-Agent': "Magic Browser"})
response = urllib2.Request.urlopen(req).read()
return response
def extract(url):
url = get_content(url)
g = Goose()
article = g.extract(url=url)
resposne = {'image':article.top_image.src}
return json.dumps(resposne)
views.py
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name = 'main/add_post.html'
def form_valid(self, form):
self.object = form.save(commit=False)
# any manual settings go here
self.object.moderator = self.request.user
url = self.request.GET.get('url')
image = extract(url)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
#method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(PostCreateView, self).dispatch(request, *args, **kwargs)
In views.py do like:
def form_valid(self, form):
self.object = form.save(commit=False)
# any manual settings go here
self.object.moderator = self.request.user
url = self.request.GET.get('url', False)
if url:
image = extract(url)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))

Django FormView Not Saving

My form isn't saving the models that I need it to. My form:
class RewardForm(forms.Form):
quantity = forms.IntegerField(max_value=10, min_value=1, label=_('quantity'), initial=1)
reward = forms.CharField(max_length=50, label=_('reward'))
reward_denomination = forms.ModelChoiceField(queryset=Reward_Denomination.objects.all(), widget=forms.RadioSelect)
def clean_reward(self):
data = self.cleaned_data.get('reward')
try:
reward = Reward.objects.get(reward_name=data)
except ObjectDoesNotExist:
raise forms.ValidationError(_('Reward does not exist'), code='invalid')
return data
def clean_reward_denomination(self):
data = self.cleaned_data.get('reward_denomination')
try:
denomination = Reward_Denomination.objects.get(denomination=data)
except ObjectDoesNotExist:
raise forms.ValidationError(_('Denomination does not exist'), code='invalid')
return data
def save(self, request, commit=True):
user = request.user
data = self.cleaned_data
'try:
post_reward = data['reward']
post_denomination = data['reward_denomination']
quantity = data['quantity']
except LookupError:
raise Http404
reward = Reward.objects.get(reward_name=post_reward)
denomination = Reward_Denomination.objects.get(denomination=post_denomination)
user_points = Points.objects.filter(affiliate__id=user.id).aggregate(total_points=Sum('points'))
user_points = user_points['total_points']
try:
total_cost = (quantity * denomination.cost)
except ArithmeticError:
raise Http404
quote_price = -total_cost
if user_points >= total_cost:
reward_order = Points.objects.create(affiliate=user, points=quote_price, from_reward=True, from_offer=False)
status_coded = Status_Code.objects.create(short_name="Pending", name="The order is currently being reviewed", description="The order is in queue")
redeem_order = Redeem.objects.create(affiliate=user, status_code=status_coded, quantity=quantity, reward=reward, price=total_cost)
return reward_order
My Views:
class Reward_Detail(DetailView):
model = Reward
slug_field = 'reward_slug'
context_object_name = 'reward'
template_name = 'omninectar/reward.html'
#Detail Stuff
class RedeemReward(SingleObjectMixin, FormView):
template_name = 'omninectar/reward.html'
slug_field = 'reward_slug'
form_class = RewardForm
model = Reward
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(RedeemReward, self).post(request, *args, **kwargs)
def get_success_url(self):
return reverse('omni:reward_confirmation')
class RewardBeautify(View):
def get(self, request, *args, **kwargs):
view = Reward_Detail.as_view()
return view(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
view = RedeemReward.as_view()
return view(request, *args, **kwargs)
So I initially thought that the FormView would handle the form processing (validate, and, if valid, run form.save(), etc). I'm following the FormView, SingleObjectMixin example on the Django website. I don't receive any errors when I try and submit the form, but no objects are created either. I've tried defining a form_valid method that runs the save method, I've tried putting it inside the post method in the formview, etc. Can anyone spot the error/errors? Thanks!
I'm new to view classes too and I had almost the same problem with Django 1.6.
You should add
def form_valid(self, form):
form.save()
return super(RedeemReward, self).form_valid(form)
method overriding to your RedeemReward class. This worked for me.
If you look to Django source code, you will see that there is no form saving in FormView class inheritance chain.
I am not sure if this will help or not, but I had issues finding code showing how to save the data from a FormView model. This is what I came up with. I hope it helps and you can apply it to your code.
forms.py
class JobCreateForm(forms.Form):
title = forms.CharField(label='Job Title', max_length=500)
number = forms.IntegerField(label='Job Number: ')
comps = forms.ModelMultipleChoiceField(label='Comparable Sales',
required=False, queryset=m.ComparableSale.objects.all())
details = forms.CharField(label='Job Details:', max_length=200,
required=False, widget=forms.Textarea(attrs={'rows':6, 'cols':20}))
Views.py
class JobCreateView(generic.FormView):
template_name = 'form_templates/createjob_form.html'
form_class = f.JobCreateForm
model = models.Job
success_url = '/'
def form_valid(self, form):
comps = form.cleaned_data['comps']
title = form.cleaned_data['title']
number = form.cleaned_data['number']
details = form.cleaned_data['details']
job = models.Job(title=title, number=number, details=details)
job.save()
print(comps)
if comps != []:
job.comps.add(*comps)
return super(JobCreateView, self).form_valid(form)
You can write your own ModelFormView using the mixins provided by Django (specifically, the ModelFormMixin). Then your form will be saved on a successful post.
from django.views.generic.base import TemplateResponseMixin
from django.views.generic.edit import ModelFormMixin, ProcessFormView
class BaseModelFormView(ModelFormMixin, ProcessFormView):
pass
class ModelFormView(TemplateResponseMixin, BaseModelFormView):
pass

Categories

Resources