I am working on a view with 2 tabs, in each tab a different list should be displayed. Here's an example of views.py file.
class IndexView(LoginRequiredMixin, TemplateView):
template_name = 'index.html'
login_url = reverse_lazy('login')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
today = datetime.today()
start_week = today - timedelta(today.weekday())
end_week = start_week + timedelta(7)
context['dayli_expirations'] = Member.objects.filter(
expiration_date__day=today.day,
expiration_date__month=today.month,
expiration_date__year=today.year
)
context['weekly_expirations'] = Member.objects.filter(expiration_date__range=[start_week, end_week])
return context
Why get_queryset() from MonthArchiveView returns all objects from my model instead objects created only in requested month?
class BudgetMonthlyView(MonthArchiveView):
template_name = 'budget/monthly.html'
model = FinanceData
date_field = "created"
make_object_list = False
allow_future = False
month_format = '%m'
def get_context_data(self, **kwargs):
context = super(BudgetMonthlyView, self).get_context_data(**kwargs)
print(self.get_queryset()) #return all objects from FinanceData model
print(context['object_list']) #works fine
return context
It's just the way that the MonthArchiveView is implemented. If you look at the source code, you can see that the object_list is returned by the get_dated_items method.
It's probably implemented this way because the date archive views add other things to the context as well as the object_list, for example date_list.
class BudgetMonthlyView(MonthArchiveView):
template_name = 'budget/monthly.html'
queryset = FinanceData.objects.all()
date_field = "created"
make_object_list = True
allow_future = False
month_format = '%m'
paginate_by = 50
context_object_name = 'object_list'
def get_context_data(self, **kwargs):
context = super(BudgetMonthlyView, self).get_context_data(**kwargs)
month = self.get_month() # get month
context['month'] = self.queryset.filter(created__month=month) # you can aggregate for this month ' .aggregate(Sum('cost'))['cost__sum'] '
print(context['object_list']) #works fine
return context
class EditShipment(LoginRequiredMixin, FormView):
template_name = "add-edit-shipment.html"
model = Shipment
form_class = ShipmentForm
success_url = lazy(reverse,str)("shipment_listing")
def get_context_data(self, **kwargs):
context = super(EditShipment,self).get_context_data(**kwargs)
context['shpid'] = self.kwargs.get('shpid',None)
context['key'] = 'edit'
return context
def get_initial(self):
ship_obj = Shipment.objects.get(id=int(self.kwargs.get('shpid',None)))
stdr_obj = Shipment_Truck_Driver_Relation.objects.get(shipment = ship_obj)
return {'origin_address':ship_obj.origin_address,\
'destination_address':ship_obj.destination_address,\
'total_weight':ship_obj.total_weight,'pick_up':ship_obj.pick_up,\
'delivery':ship_obj.delivery,'amount':ship_obj.amount,\
'truck':stdr_obj.truck,'driver':stdr_obj.driver}
def get_form(self, form_class):
return form_class(initial=self.get_initial())
def form_valid(self,form):
import ipdb;ipdb.set_trace()
userprofile_obj = User_Profile.objects.get(user = self.request.user)
compuser_obj = Company_Users.objects.get(user_profile = userprofile_obj)
self.f = form.save(commit=False)
self.f.total_weight = self.request.POST.get('total_weight')
self.f.pickup_cutoff = self.request.POST.get('pick_up')
self.f.delivery_cutoff = self.request.POST.get('delivery')
self.f.customer, self.f.created_by = compuser_obj.company, userprofile_obj
self.f.save()
return super(EditShipment, self).form_valid(form)
Here form_valid is not saving but its not throwing any error, also the object values are not updated.
How to save in def form_valid?
I have this url is http://127.0.0.1:8000/upload/picturelist/1, which makes user_id = 1,
In my urls.py
url(r'^picturelist/(?P<user_id>\d+)$', views.pictureList),
In my view.py
def pictureList(request, user_id):
if int(user_id) != request.user.id:
raise PermissionDenied
How can I make this function based view to use createview?
class pictureList(CreateView):
You could do something like this:
In urls.py: url(r'^picturelist/(?P<user_id>\d+)$', views.MakeItView.as_view()),
In views.py:
class MakeItView(CreateView):
model = myModel
template_name = 'whatever.html'
def get_context_data(self, **kwargs):
context = super(MakeItView, self).get_context_data(**kwargs)
if int(self.kwargs['user_id']) != self.request.user.id:
raise PermissionDenied
return context
I've never used CreateView, but here's what I gather from reading the docs:
You could do it by defining form_valid:
view:
class pictureList(CreateView):
model = YourModelHere
fields = ['whatever','fields','you','want','edited']
def form_valid(self, form):
record = form.save(commit = False)
# assuming the user id is associated
# to the model with fieldname user_id
if (self.request.user == record.user_id):
record.save()
return HttpResponseRedirect(self.get_success_url())
# not sure if this works:
return self.form_invalid()
Then the template would be at 'yourappname/yourmodelhere_form.html'.
See CreateView for an example.
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