'class' object has no attribute 'object' - python

What am i doing wrong here. I have been trying to figure this out for hours. I think i am having issues with Django get_context_data function.
Error is 'PatientBedAllotmentList' object has no attribute 'object'
views.py
#method_decorator(login_required, name='dispatch')
class PatientBedAllotmentList(ListView):
model = BedAllotment
template_name = 'room/bed_allotment_list.html'
def get_context_data(self, **kwargs):
context = super(PatientBedAllotmentList, self).get_context_data(**kwargs)
start = BedAllotment.objects.get(id=self.object.id).allotment_date
end = BedAllotment.objects.get(id=self.object.id).departure_date
amount = BedCreate.objects.get(id=self.object.id).cost
days_number = abs((end - start).days)
days_number = int(days_number)
amount_due = amount * days_number
context['account_type'] = AccountUser.objects.get(user_id=self.request.user.id)
hospital_id = AccountUser.objects.get(user_id=self.request.user.id).hospital_id
allotment_details = BedAllotment.objects.filter(hospital_id=hospital_id)
context['allotment'] = allotment_details
context['amount'] = amount_due
return context
urls.py
from django.conf.urls import url
from medisaver.room import views
urlpatterns = [
url(r'^room-category/create/$', views.RoomCategoryCreate.as_view(), name='room_category_create'),
url(r'^room-category/list/$', views.RoomCategoryList.as_view(), name='room_category_list'),
url(r'^room-category/update/(?P<hospital_id>[0-9A-Fa-f-]+)/(?P<category_id>[0-9]+)/$', views.RoomCategoryUpdate.as_view(), name='room_category_update'),
url(r'^room-category/delete/(?P<hospital_id>[0-9A-Fa-f-]+)/(?P<category_id>[0-9]+)/$', views.RoomCategoryDelete.as_view(), name='room_category_delete'),
url(r'^hospital-rooms/list/$', views.RoomList.as_view(), name='room_list'),
url(r'^hospital-rooms/create/$', views.RoomCreateView.as_view(), name='room_create'),
url(r'^hospital-rooms/update/(?P<category_id>[0-9]+)/(?P<room_id>[0-9]+)/$', views.RoomUpdate.as_view(), name='room_update'),
url(r'^hospital-rooms/delete/(?P<category_id>[0-9]+)/(?P<room_id>[0-9]+)/$', views.RoomDelete.as_view(), name='room_delete'),
url(r'^hospital-rooms/beds/create/$', views.BedCreateView.as_view(), name='bed_create'),
url(r'^hospital-rooms/beds/list/$', views.BedList.as_view(), name='bed_list'),
url(r'^hospital-rooms/beds/update/(?P<room_id>[0-9]+)/(?P<bed_id>[0-9]+)/$', views.BedUpdate.as_view(), name='bed_update'),
url(r'^hospital-rooms/beds/delete/(?P<room_id>[0-9]+)/(?P<bed_id>[0-9]+)/$', views.BedDelete.as_view(), name='bed_delete'),
url(r'^hospital-rooms/beds/patient-bed-allotment/$', views.BedAllotmentCreate.as_view(), name='bed_allotment'),
url(r'^hospital/discharge-patient/(?P<allotment_id>[0-9]+)/(?P<patient_id>[0-9A-Fa-f-]+)/$', views.BedDischarge.as_view(), name='patient_bed_discharge'),
url(r'^hospital/bed-allotment-list/$', views.PatientBedAllotmentList.as_view(), name='patient_bed_list'),
]

self.object does not make any sense in ListView.
If you want to get stay_time then you can do it in your model and access in template using object.stay_time and even you can calculate the amount in template by multiplying. But I You can even do it in detailview. Create a method in that model like
#property
def stay_time(self):
return (self.departure_date-self.allotment_date)

I was able to fix it by calling on form_valid function. I used the function on my BedDischarge class in my views. And was able to use self.object. Then made a template call in my templates.
#method_decorator(login_required, name='dispatch')
class BedDischarge(UpdateView):
model = BedAllotment
template_name = 'room/bed_discharge.html'
form_class = BedAllotmentUpdateForm
pk_url_kwarg = 'allotment_id'
success_url = reverse_lazy('patient_bed_list')
def get_context_data(self, **kwargs):
context = super(BedDischarge, self).get_context_data(**kwargs)
context['account_type'] = AccountUser.objects.get(user_id=self.request.user.id)
return context
def form_valid(self, form):
get_allot_id = self.object.id
bed_allot = BedAllotment.objects.get(id=get_allot_id)
start_time = bed_allot.allotment_date
end_time = form.instance.departure_date
cost = BedCreate.objects.get(id=self.object.bed_id).cost
days_spent = (end_time - start_time).days
amount = cost * days_spent
form.instance.days = days_spent
form.instance.amount = amount
return super(BedDischarge, self).form_valid(form)

Related

Is possible paginate multiple arrays with templateView in different contexts?

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

get_queryset() in MonthArchiveView returns all objects instead objects created only in requested month

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

Django CBV FormView get_intial form_valid not saving but it's saving with def post

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?

Django function based view to class based view

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.

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