django modelform submission - django

I am working on a django project, The model CaseRegister i am trying to submit values using model form. My model class belo
- model.py
from django.db import models
from core.models import ProviderMaster,FacilityMaster,ProviderMaster,CaseMaster,CasestatusMaster
from patient.models import PatientMaster
from django.contrib.auth.models import User
from django.forms import ModelForm
from account.models import Profile
def update_id(func):
def decorated_function(*args):
data_object = args[0]
sequence_name = 'seq_%s' % data_object._meta.db_table
from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT nextval(%s)", [sequence_name])
row = cursor.fetchone()
data_object.caseid = row[0]
return func(*args)
return decorated_function
class CaseRegister(models.Model):
caseid = models.DecimalField(primary_key=True, max_digits=8, decimal_places=0)
patient = models.ForeignKey(PatientMaster, on_delete=models.CASCADE, db_column='patientid')
case_startdate = models.DateField()
case_enddate = models.DateField(blank=True, null=True)
providerid = models.ForeignKey(ProviderMaster, models.DO_NOTHING, db_column='providerid', blank=True, null=True)
facilityid = models.ForeignKey(FacilityMaster, models.DO_NOTHING, db_column='facilityid', blank=True, null=True)
casetypeid = models.ForeignKey(CaseMaster, models.DO_NOTHING, db_column='casetypeid', blank=True, null=True)
casestatus = models.ForeignKey(CasestatusMaster, models.DO_NOTHING, db_column='casestatus', blank=True, null=True)
approved_date = models.DateField(blank=True, null=True)
last_modifieduser = models.ForeignKey(Profile,on_delete=models.CASCADE, db_column='last_modifieduser')
class Meta:
managed = False
db_table = 'case_register'
def __str__(self):
return self.caseid
#update_id
def save(self):
# Now actually save the object.
super(CaseRegister, self).save()
The form is created as below and mapped query set for all FK fields
- The form.py
from django import forms
from .models import CaseRegister
from patient.models import PatientMaster
from django.contrib.auth.models import User
from account.models import Profile,ProfileFaciltiyMembership
from core.models import FacilityMaster,CasestatusMaster,ProviderMaster,ProviderCategory,RoleMaster
from django.db.models import Q
import datetime
class CaseRegisterForm(forms.ModelForm):
class Meta:
model = CaseRegister
fields = ('caseid', 'patient', 'case_startdate',"case_enddate","facilityid","providerid","casetypeid","casestatus","last_modifieduser" )
def __init__(self, p,profile,request, *args, **kwargs):
super(CaseRegisterForm, self).__init__(*args, **kwargs)
print("request.method "+request.method)
if (request.method=='GET'):
print("request.method "+request.method)
self.fields['patient'].empty_label = None
self.fields['patient'].label="Patient"
self.fields['patient'].queryset = PatientMaster.objects.filter(patientid=p.patientid)
self.fields['patient'].widget.attrs = {'maxlength': 10}
self.fields['patient'].widget.attrs = {'disabled': True}
self.fields['case_startdate'].widget.attrs = {'class': 'vDateField'}
self.fields['case_startdate'].label="Date"
self.fields['case_startdate'].initial=datetime.datetime.now().date()
#self.fields['last_modifieduser'].queryset = Profile.objects.filter(user=profile.user)
self.fields['last_modifieduser'].queryset = Profile.objects.all()
self.fields['last_modifieduser'].empty_label = None
#self.fields['last_modifieduser'].widget = forms.HiddenInput()
self.fields['caseid'].required = False
self.fields['caseid'].widget = forms.HiddenInput()
self.fields['case_enddate'].widget = forms.HiddenInput()
fid = request.session["currfacility"]
self.fields['facilityid'].empty_label = None
self.fields['facilityid'].queryset = FacilityMaster.objects.filter(facilityid=fid)
self.fields['facilityid'].widget.attrs = {'disabled': True}
self.fields['casestatus'].empty_label = None
self.fields['casestatus'].queryset=CasestatusMaster.objects.filter(casestatusid=1)
facility=FacilityMaster.objects.get(pk=fid)
profiles=Profile.objects.filter(facilities=facility)
providercat = ProviderCategory.objects.get(pk=2)
self.fields['providerid'].empty_label = None
self.fields['providerid'].label="Physician"
self.fields['casetypeid'].label="Type"
self.fields['casetypeid'].empty_label = None
self.fields['casestatus'].label="Status"
criterion1 = Q(profile__in=profiles)
criterion2 = Q(pcategoryid=providercat)
rid = request.session["currrole"]
print(rid)
if rid == str(2) :
print("if")
profile = request.user.profile
pfid = profile.provider.providerid
print(pfid)
criterion3 = Q(providerid=pfid)
self.fields['providerid'].queryset = ProviderMaster.objects.filter(criterion3 & criterion2)
else:
print("else")
self.fields['providerid'].queryset = ProviderMaster.objects.filter(criterion1 & criterion2)
The below is the view and inthe GET method i am assigning a patient id and in
POST request i am not doing anything to the modelform.
- view.py
from django.shortcuts import render,redirect
from .forms import CaseRegisterForm
from .models import CaseRegister
from patient.models import PatientMaster
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import CreateView, DetailView, UpdateView
def caseregister(request):
pid =1413963
if request.method == "POST":
form = CaseRegisterForm(None,request.user.profile,request,request.POST)
#form = CaseRegisterForm(request.POST)
print(form.is_valid())
print(form.errors)
if form.is_valid():
model_instance = form.save(commit=False)
model_instance.save()
return redirect('{% url "createcase" %}')
else:
pid =1413963
p = PatientMaster.objects.get(pk=pid)
form = CaseRegisterForm(p,request.user.profile,request)
return render(request, "case_register.html", {'form': form})
While submitting the form i am getting the error - patient -This field is required message.
I tried to map query set patient in post method same as like get. I am getting the same error.

Related

"null value in column violates not-null constraint" When saving Django Form

I am getting the following error in my code:
"null value in column "bbso_record_id_id" of relation "sos_categorytoolsandequipment" violates not-null constraint DETAIL: Failing row contains (1, 1, , null)."
The thing this, the code I have works with SQLlite but since I upgraded to Postgress all of a sudden it breaks and if I go back to SQllite it works again.
I realize that the problem is with the OneToOne relationship but I am not sure how to retify it. It seems like my BBSO_Record has to save and get an id to pass to the OneToOne field first. But the problem is it works in SQLlite.
This is my code and any assistance will be greatly appreciated.
MODELS
from django.db import models
from django.db.models.deletion import CASCADE
from django.core.validators import RegexValidator, MinValueValidator, MaxValueValidator
#from django.db.models.enums import choices
from django.utils import timezone
from django.urls import reverse # page 138 Django for Beginneers
from django.conf import settings #
from django.utils import timezone
from django.utils.timezone import now
class BBSO_Records(models.Model):
COMPANY_OR_CONTRACTOR = (
('company', 'Company'),
('contractor', 'Contractor'),
)
severityLevel = (
('1', 'Level 1'),
('2', 'Level 2'),
('3', 'Level 3'),
)
severity_level = models.CharField(max_length=6, default= 3 , choices=severityLevel)
date_recorded = models.DateField()
observer_name_ID = models.ForeignKey(settings.AUTH_USER_MODEL , on_delete=models.PROTECT, verbose_name="Observer Name") # i need to double check how I would be handling this.
observer_department_ID = models.ForeignKey(Observer_Department, on_delete=models.PROTECT, verbose_name="Observer Department")
site_location_ID = models.ForeignKey(Site_Locations, on_delete=models.PROTECT, verbose_name='Location of Observation')
location_details = models.CharField(max_length=50, help_text='e.g. In the kitchen on the 4th floor.', blank=True)
company_or_contractor = models.CharField(max_length=10, choices=COMPANY_OR_CONTRACTOR)
number_of_persons_observed = models.IntegerField(default=1, validators=[MinValueValidator(0),
MaxValueValidator(25)],verbose_name='# of Persons Observed') # https://stackoverflow.com/questions/849142/how-to-limit-the-maximum-value-of-a-numeric-field-in-a-django-model
# time_spent = models.IntegerField(verbose_name="Time Spent Observing (mins)", default=True)
PTW = models.CharField(max_length=10, verbose_name="Permit To Work Number", blank=True)
JSA = models.CharField(max_length=10,verbose_name="Job Safety Analysis Number", blank=True)
bbso_title = models.CharField(max_length=100,verbose_name="Title of Observation", help_text='e.g. Contractor Employee not wearing correct PPE for the job (i.e. wrong gloves).')
details_of_observation = models.TextField()
date_created = models.DateTimeField(auto_now_add=True, editable=True) # setting editable equal=False wouldnot make this contorl show on the form
date_updated = models.DateTimeField(auto_now=True, editable=True)
def __str__(self) :
return f'ID:{self.id} ; SOS Title: {self.bbso_title}; Date Recorded: {self.date_recorded}'
def has_related_object(self):
return hasattr(self, 'CategoryToolsAndEquipment')
def get_absolute_url(self):
return reverse ('bbso_records_detail', args=[str(self.id)])
class Meta:
ordering = ["date_created"]
verbose_name_plural = "BBSO_Records"
# unique_together = ('field_1', 'field_2',)
class CategoryToolsAndEquipment (models.Model):
ACCEPTABLE_UNACCEPTABLE = (
('1', 'ACCEPTABLE'),
('0', 'UNACCEPTABLE'),
)
bbso_record_id = models.OneToOneField(BBSO_Records, on_delete=models.CASCADE, primary_key=True )
right_for_the_job = models.CharField(max_length=1, blank=True, choices=ACCEPTABLE_UNACCEPTABLE)
in_fit_for_use_condition = models.CharField(max_length=1, blank=True, choices=ACCEPTABLE_UNACCEPTABLE)
used_correctly = models.CharField(max_length=1,blank=True, choices=ACCEPTABLE_UNACCEPTABLE)
def __str__(self):
return self.right_for_the_job
class Meta:
verbose_name_plural = "CategoryToolsAndEquipment"
FORMS
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Column, Layout, Field, Fieldset, Div, Row, HTML, ButtonHolder, Submit
from crispy_forms.bootstrap import TabHolder, Tab
# 3rd Party
from .widgets import XDSoftDateTimePickerInput
from .custom_layout_object import Formset
# from bootstrap_datepicker_plus import DatePickerInput, DateTimePickerInput
# forms
from django import forms
from django.forms import ModelForm, Textarea
from django.forms.models import inlineformset_factory
# models
from .models import BBSO_Records, BBSO_Record_Actions, Category_PPE
from .models import CategoryToolsAndEquipment
from .models import Category_Environmental
from .models import Category_Driving
from .models import Category_Health_Hygiene
# from .models import Category_Peoples_Reactions
from .models import Category_Potential_For_Injury
from .models import Category_Permts_and_Procedures
from .models import Category_Workspace_Ergonomics
from .models import Category_Housekeeping
from .models import Site_Locations
from .models import Company, Classification_Code, Site_Locations, Observer_Department
class DateInput(forms.DateInput):
input_type = 'date'
class BBSORecordsForm(ModelForm):
# date_recorded = forms.DateTimeField(input_formats=['%d/%m/%Y %H:%M'], widget=XDSoftDateTimePickerInput())
# observer_name_ID = forms.CharField(widget=forms.HiddenInput())
class Meta:
model = BBSO_Records
fields = '__all__'
exclude = ('observer_name_ID',)
widgets = {
'date_recorded': DateInput(),
# 'id': forms.HiddenInput()
}
# widgets = { 'date_recorded': DateTimePickerInput(options={"showClose": True,"showClear": True,"showTodayButton": True,}), }
# https://pypi.org/project/django-bootstrap-datepicker-plus/
# exclude = ['date_created', 'date_updated']
def __init__(self, *args, **kwargs):
super(BBSORecordsForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = True
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'col-sm-3 create-label'
self.helper.field_class = 'col-sm-9'
self.helper.attrs = {'novalidate':''} # this is to remove crispyform validation from pop up to red
self.helper.attrs['autocomplete'] = 'off'
self.helper.layout = Layout(
Div(
Field('id'),
Field('severity_level'),
Field('date_recorded'), # css_class='form-group'
Field('observer_department_ID'),
Field('site_location_ID'),
Field('location_details'),
Field('company_or_contractor'),
Field('number_of_persons_observed'),
Field('PTW'),
Field('JSA'),
Field('bbso_title'),
Field('details_of_observation', id='mytextarea'), # https://www.tiny.cloud/docs/quick-start/
# Field('observer_name_ID'),
TabHolder(
Tab('Tools & Equipment', Formset('category_tools_equipment')), # this takes the name from the view which is passed here: bbso_record_actions = context['bbso_record_actions']
Tab('PPE', Formset('category_ppe')),
Tab('Environmental', Formset('category_environmental')),
Tab('Driving', Formset('category_driving')),
Tab('Health & Hygiene', Formset('category_healthhygiene')),
Tab('Potential for Injury', Formset('category_potential_for_injury')),
Tab('Permits & Procedures', Formset('category_permtis_and_procedures')),
Tab('Workspace Ergonomics', Formset('category_workspace_ergonomics')),
Tab('Housekeeping', Formset('category_housekeeping')),
# Tab('Tools & Equipment',Formset('categorytoolsAndEquipment'))
),
TabHolder(
Tab('SOS Actions', Formset('bbso_record_actions'))
# Field('field_name_3', css_class="extra")
# Div('field_name_2')
),
# Fieldset('Add SOS Actions', Formset('bbso_record_actions')),
HTML("<br>"),
ButtonHolder(Submit('submit', 'Save', css_class='btn btn-primary btn-xs')),
)
)
class CategoryToolsAndEquipmentForm(ModelForm):
class Meta:
model = CategoryToolsAndEquipment
fields = '__all__'
def __init__(self, *args, **kwargs):
super(CategoryToolsAndEquipmentForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'col-sm-3 create-label'
self.helper.field_class = 'col-sm-9'
CategoryToolsAndEquipmentFormset = inlineformset_factory(BBSO_Records,
CategoryToolsAndEquipment,
fields = [ 'right_for_the_job',
'in_fit_for_use_condition',
'used_correctly' ],
form = CategoryToolsAndEquipmentForm,
can_delete=False)
VIEW
class BBSORecord_NestedForm_CreateView(LoginRequiredMixin, CreateView): # main form and nested form for BBSO Records
model = BBSO_Records
template_name = 'sos/bbso_records/bbso_record_create.html' # 'sos/bbso_records/bbso_record_nested_new.html'
form_class = BBSORecordsForm
# fields = ('date_recorded','time_of_observation', 'observer_department_ID', 'site_location_ID',
# 'location_details', 'company_or_contractor','number_of_persons_observed', 'time_spent',
# 'PTW', 'JSA', 'details_of_observation')
# exclude = ('observer_name_ID')
# success_url = None # reverse_lazy('home')
def get_context_data(self, **kwargs):
data = super(BBSORecord_NestedForm_CreateView, self).get_context_data(**kwargs)
if self.request.POST:
data['bbso_record_actions'] = BBSO_Record_ActionsFormset(self.request.POST)
data['category_tools_equipment'] = CategoryToolsAndEquipmentFormset(self.request.POST)
data['category_ppe'] = CategoryPPEFormset(self.request.POST)
data['category_environmental'] = CategoryEnvironmentalFormset(self.request.POST)
data['category_driving'] = CategoryDrivingFormset(self.request.POST)
data['category_healthhygiene'] = CategoryHealthHygieneFormset(self.request.POST)
data['category_potential_for_injury'] = CategoryPotentialForInjuryFormset(self.request.POST)
data['category_permtis_and_procedures'] = CategoryPermitsandProceduresFormset(self.request.POST)
data['category_workspace_ergonomics'] = CategoryWorkspaceErgonomicsFormset(self.request.POST)
data['category_housekeeping'] = CategoryHouseKeepingFormset(self.request.POST)
else:
data['bbso_record_actions'] = BBSO_Record_ActionsFormset()
data['category_tools_equipment'] = CategoryToolsAndEquipmentFormset()
data['category_ppe'] = CategoryPPEFormset()
data['category_environmental'] = CategoryEnvironmentalFormset()
data['category_driving'] = CategoryDrivingFormset()
data['category_healthhygiene'] = CategoryHealthHygieneFormset()
data['category_potential_for_injury'] = CategoryPotentialForInjuryFormset()
data['category_permtis_and_procedures'] = CategoryPermitsandProceduresFormset()
data['category_workspace_ergonomics'] = CategoryWorkspaceErgonomicsFormset()
data['category_housekeeping'] = CategoryHouseKeepingFormset()
return data
def form_valid(self, form):
context = self.get_context_data()
bbso_record_actions = context['bbso_record_actions']
category_tools_equipment = context['category_tools_equipment']
category_ppe = context['category_ppe']
category_environmental = context['category_environmental']
category_driving = context['category_driving']
category_healthhygiene = context['category_healthhygiene']
category_potential_for_injury = context['category_potential_for_injury']
category_permtis_and_procedures = context['category_permtis_and_procedures']
category_workspace_ergonomics = context['category_workspace_ergonomics']
category_housekeeping = context['category_housekeeping']
with transaction.atomic():
form.instance.observer_name_ID = self.request.user
self.object = form.save() #moved to inside the .is_valid
if bbso_record_actions.is_valid():
bbso_record_actions.instance = self.object
bbso_record_actions.save()
# if category_tools_equipment.is_valid():
category_tools_equipment.instance = self.object
category_tools_equipment.save()
category_ppe.instance = self.object
category_ppe.save()
category_environmental.instance = self.object
category_environmental.save()
category_driving.instance = self.object
category_driving.save()
category_healthhygiene.instance = self.object
category_healthhygiene.save()
category_potential_for_injury.instance = self.object
category_potential_for_injury.save()
category_permtis_and_procedures.instance = self.object
category_permtis_and_procedures.save()
category_workspace_ergonomics.instance = self.object
category_workspace_ergonomics.save()
# if category_housekeeping.is_valid():
category_housekeeping.instance = self.object
category_housekeeping.save()
return super(BBSORecord_NestedForm_CreateView, self).form_valid(form)
else:
return self.render_to_response(self.get_context_data(form=form))
def get_success_url(self):
return reverse_lazy('bbso_records_detail', kwargs={'pk': self.object.pk})
custom_layout_object.py
from crispy_forms.layout import LayoutObject #, TEMPLATE_PACK
from crispy_forms.utils import TEMPLATE_PACK
from django.shortcuts import render
from django.template.loader import render_to_string
###### Thanks!
###### https://stackoverflow.com/questions/15157262/django-crispy-forms-nesting-a-formset-within-a-form/22053952#22053952
class Formset(LayoutObject):
template = "mycollections/formset.html"
def __init__(self, formset_name_in_context, template=None):
self.formset_name_in_context = formset_name_in_context
self.fields = []
if template:
self.template = template
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
formset = context[self.formset_name_in_context]
return render_to_string(self.template, {'formset': formset}, context['request'])
Hey Guys, this is the last thing to complete my form and any help will be greatly appreicated!
It's a good practice to link your project to any DBMS before writing any models, I suggest that you create migrations again with the project linked to Postgres, also try to provide a default record for any OneToOne, FK etc... field:
for example:
bbso_record_id = models.OneToOneField(BBSO_Records, on_delete=models.CASCADE, primary_key=True,default=1)

Django - Class Based View trouble How Combine DetailView with ListView in same template

can anyone tell me how combine detailview with list view and show info in the same template, i'll explain you, i'm learning Django and i am trying to create a Questions and Answer web app, and i need to show the question with all its awnsers, i need in my detailview for a specific question show below all it awsers, something like stackoverflow does
#models.py
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
# Create your models here.
class Question(models.Model):
# user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="question", null=True)
name = models.CharField(max_length=100)
description = models.TextField(max_length=100)
date = models.DateTimeField(auto_now_add=True)
cant_resp = models.IntegerField(default=0)
question_type = models.CharField(max_length=50, choices=QUESTION_TYPES_CHOICES)
def __str__(self):
return self.description
class Anwser(models.Model):
# user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="anwser", null=True)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
text = models.TextField(max_length=400)
date= models.DateTimeField(auto_now_add=True)
#and this are my views.py
from django.shortcuts import render, redirect
from django.urls import reverse, reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import generic
from .forms import QuestionForm, AnwserForm
from .models import Question
# Create your views here.
class QuestionListView(LoginRequiredMixin, generic.ListView):
template_name = 'anwserquestions/question_list.html'
context_object_name = 'questions'
def get_queryset(self):
return Question.objects.all()
def createquestion(response):
if response.method == "POST":
print("Its POST method")
form = QuestionForm(response.POST)
# user =response.user
if form.is_valid():
name = form.cleaned_data["name"]
description=form.cleaned_data['description'],
question_type=form.cleaned_data['question_type'],
# date=form.cleaned_data['date'],
t = Question(name=name, description=description, question_type=question_type, cant_resp=0)
t.save()
response.user.question.add(t) # adds the to do list to the current logged in user
# return HttpResponseRedirect("/%i" %t.id)
return redirect('anwserquestions:question-list')
else:
form = QuestionForm()
return render(response, "anwserquestions/question_create.html", {"form":form})
class QuestionDetailView(LoginRequiredMixin, generic.DetailView):
model = Question
template_name = 'anwserquestions/question_detail.html'
context_object_name = 'question'
def get_queryset(self):
return Question.objects.all()
class QuestionDeleteView(LoginRequiredMixin, generic.DeleteView):
template_name = 'anwserquestions/question_delete.html'
context_object_name = 'question'
success_url = reverse_lazy('anwserquestions:question-delete')
# def get_queryset(self):
# return Question.objects.all()
You can get the related answers by including it in the views context, so you QuestionDetailView becomes
class QuestionDetailView(LoginRequiredMixin, generic.DetailView):
model = Question
template_name = 'anwserquestions/question_detail.html'
context_object_name = 'question'
def get_context_data(self, **kwargs):
context = super(QuestionDetailView, self).get_context_data(**kwargs)
context['answers'] = Answer.objects.filter(post=self.get_object())
return context

Django to clear data causing save() prohibited to prevent data loss due to unsaved related object

I need to know how to clear the unsaved related data which causes the following error:
save() prohibited to prevent data loss due to unsaved related object 'order'.
My code is working as intended, but I failed to complete an order. Ever since this, any attempt to save a new order results in above error. I am aware of the cause being the changes to django.db.models.base.py, but there must be some way to clear this via logs or something...
I have tried recreating the database, and also the sqlflush command but neither is working.
VIEWS
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import weasyprint
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.admin.views.decorators import staff_member_required
from django.core.urlresolvers import reverse
from django.conf import settings
from django.http import HttpResponse
from django.template.loader import render_to_string
from .models import OrderItem, Order
from .forms import OrderCreateForm
from cart.cart import Cart
from .tasks import order_created
# Create your views here.
#staff_member_required
def admin_order_detail(request, order_id):
order = get_object_or_404(Order, id=order_id)
return render(request, 'admin/orders/order/detail.html', {'order': order})
#staff_member_required
def admin_order_pdf(request, order_id):
order = get_object_or_404(Order, id=order_id)
html = render_to_string('orders/order/pdf.html', {'order': order})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename="order_{}.pdf"'.format(order.id)
weasyprint.HTML(string=html).write_pdf(response, stylesheets=[weasyprint.CSS(settings.STATIC_ROOT + 'css/pdf.css')])
return response
def order_create(request):
cart = Cart(request)
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
if cart.coupon:
order.coupon = cart.coupon
order.discount = cart.coupon.discount
order.save()
for item in cart:
OrderItem.objects.create(order=order, product=item['product'], price=item['price'], quantity=item['quantity'])
#emptying the cart
cart.clear()
#launch celery async task
order_created.delay(order.id)
request.session['order_id'] = order.id #set order.id session
return redirect(reverse('payment:process'))
else:
form = OrderCreateForm()
return render(request, 'orders/order/create.html', {'cart': cart, 'form':form})
MODELS
class Order(models.Model):
first_name = models.CharField(_('first_name'),max_length=50)
last_name = models.CharField(_('last_name'),max_length=50)
email = models.EmailField(_('email'),)
address = models.CharField(_('address'),max_length=250)
postal_code = models.CharField(_('postal_code'),max_length=250)
city = models.CharField(_('city'),max_length=100)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
coupon = models.ForeignKey(Coupon, related_name='orders', null=True, blank=True)
discount = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(100)])
class Meta:
ordering = ('-created',)
def __unicode__(self):
return 'Order {}'.format(self.id)
def get_total_cost(self):
total_cost = sum(item.get_cost() for item in self.items.all())
return total_cost - total_cost *(self.discount)
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items')
product = models.ForeignKey(Product, related_name='order_items')
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
def __unicode__(self):
return '{}'.format(self.id)
def get_cost(self):
return self.price * self.quantity
FORMS
from django import forms
from .models import Order
class OrderCreateForm(forms.ModelForm):
class Meta:
model = Order
fields = ['first_name', 'last_name', 'email', 'address', 'postal_code', 'city']
If you check your models, then you can see that the coupon field in the order table is a foreign key, in other words, a related object.
Because you don't save the coupon object, it doesn't have a pk and can't be added to the order. First save the coupon object, and then add it to the order.
So something like:
coupon = cart.coupon # not sure if this in between step is needed
coupon.save()
order.coupon = coupon
order.save()
SOLVED
simply save the order object a little earlier in the code so within the orders.views.py file, within the create_order() method, add an earlier invocation of order.save() ...
THIS
if form.is_valid():
order = form.save(commit=False)
BECOMES
if form.is_valid():
order = form.save(commit=False)
order.save()
if cart.coupon:
............
..............
All working fine again!!
#Snackoverflow thks for all your help :-)

Is_valid method return false in the second time using

I write the unittest for my post function,but in the second time,It's always fail.here is my forms.py
from django import forms
from django.contrib.auth.models import User
from django.utils import timezone
from models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
here is my models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
post_author = models.ForeignKey(User)
created_at = models.DateTimeField()
update_at = models.DateTimeField()
post_title = models.TextField(blank=True)
activity_address = models.TextField(blank=True)
post_content = models.TextField()
post_type = models.CharField(max_length=50, choices=[('activity', 'activity', ), ('blog', 'blog')])
post_status = models.CharField(max_length=50, choices=[('open', 'open'), ('locked', 'locked') ])
here is the postlib.py
from models import Post
from forms import PostForm
from django.utils import timezone
def create(data):
if not data['created_at']:
data['created_at'] = timezone.now()
if not data['update_at']:
data['update_at'] = timezone.now()
post_form = PostForm(data=data)
if post_form.is_valid():
post = post_form.save()
else:
post = None
return post
and the unittest code
from django.test import TestCase
from django.utils import timezone
from Publish.forms import PostForm
from Publish.models import Post
from Publish import postlib
from django.contrib import auth
from django.contrib.auth.models import User
class PublishTest(TestCase):
def setUp(self):
User.objects.create_user(username='test', email='test#test.com', password='abc')
self.user = auth.authenticate(username="test", password='abc')
self.data = {'post_author': '1',
'post_title': 'test',
'post_content': 'nothing',
'activity_address': 'New York',
'created_at': '',
'update_at': '',
'post_type': 'activity',
'post_status': 'open'}
def test_a(self):
post = postlib.create(self.data)
self.assertNotEqual(post, None)
def test_b(self):
post = postlib.create(self.data)
self.assertNotEqual(post, None)
In the unittest,It always have a failure,either test_a or test_b,and the reason of failure is the form.is_valid(). the Is_valid() method will fail sometime,but I use the same data,How can it be?
PS:the post_form error is
'Select a valid choice. That choice is not one of the available choices.'

Question On Django Form Models

I am working on form models and get this error:
global name 'AdForm' is not defined
In my view I have:
from django.template import RequestContext, loader
from django.http import HttpResponse
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django import forms
#login_required
def create(request):
if request.POST:
ad = AdForm(request.POST)
if ad.is_valid():
test = 'valid'
else:
test = 'invalid'
else:
test = 'none'
template = loader.get_template('ads/create.html')
context = RequestContext(request, {
'test': test
})
return HttpResponse(template.render(context))
However it is not picking up my model. My model in my view is:
from django.db import models
from django.forms import ModelForm
TYPE_CHOICES = (
'Image',
'Code',
)
SIZE_CHOICES = (
'Leaderboard',
'Banner',
'Skyscraper',
'Square',
)
class Ad(models.Model):
title = models.CharField(max_length=40)
type = models.CharField(max_length=7)
size = models.CharField(max_length=16)
clicks = models.IntegerField()
media = models.ImageField(upload_to='ads')
link = models.URLField(null=True)
created = models.DateTimeField(auto_now_add=True)
expires = models.DateTimeField(null=True)
def __unicode__(self):
return self.name
class AdForm(ModelForm):
class Meta:
model = Ad
Does anyone know why it is not picking up the form model?
Thanks from a noob.
At the top of your view, you need:
from .models import AdForm
Also, forms usually go in forms.py, not with the models.