Hi I am using Django framework for my website. I've a View in project which saves data in to the database (Models). But when I run my program am getting an error as follows
ValueError: invalid literal for int() with base 10: '2015-08-24 12:27:58'
My views.py
class ProcessCheckBinningView(JSONResponseMixin, View):
#model = OrcAwaiverBin
def post(self, request, *args, **kwargs):
status = 'error'
msg = "this is from me"
post_body = json.loads(self.request.body)
fab_value = post_body['fab']
technode_value = post_body['technode']
layer_value = post_body['layer']
print fab_value, technode_value, layer_value
print "submitted from the template f"
bin_object = OrcAwaiverBin()
# Record the last accessed date
bin_object.fab = fab_value
bin_object.technology = technode_value
bin_object.layer = layer_value
print "OKKKKK"
bin_object.created_by = '2015-08-24 12:27:58'
bin_object.date_modified = '2015-08-24 12:27:58'
bin_object.save()
return self.render_json_response(dict(status=status, msg=msg))
class CheckBinningView(TemplateView):
template_name = "orc_enable.html"
def get_context_data(self, *args, **kwargs):
context = super(CheckBinningView, self).get_context_data(*args, **kwargs)
fab = GroupProfile.objects.get(id=self.request.session['ACL_gid']).fab
gp = GroupProfile.objects.get(id=self.request.session['ACL_gid'])
context['fab'] = gp.fab
context['ngapp'] = "CMOD"
return context
My Model fields:
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(blank=True)
Can someone tell me whats the problem here? Thanks in advance.
Based on what the error suggests, You should have declared the bin_object.created_by field or bin_object.date_modified field as IntegerField.
The issue was, as Aswin said my model only accept integer values. I was trying to insert datetime value. Thanks folks!
Related
Building my first Django app, and I'm running into a snag. I have a Django model that creates Job objects, and I want each job code to be unique and auto-generated, with a particular format. The format is: aaaMMnnYYYY, where aaa is a 3-letter client identifier that we set, nn is a counter that represents the nth job from that client in that month., and MM and YYYY are month and year respectively.
e.g., for the 3rd job from client "AIE" in feb 2023, the ID would be AIE02032023.
Using a calculated property with the #property decorator causes the field to be updated with every save, so I'm trying to do this by modifying the save() method. There's also a related Cost object that has a Job attribute as a Foreign Key. The way I have it now, the job code gets assigned as expected, but when I add a Cost to the Job, the 'iterating' part of the job code iterates, changing the job code, which causes uniqueness errors as well as URL errors (I'm using the job code in the URLConf. Is there any way to have this field get calculated once and then never change?
As a side note, I'd also like to be able to override the job code. Is there a way to set flags within a model, such as job_code_overridden = False, etc.?
Here's the relevant code, let me know what else you need to see.
models.py:
class Job(models.Model):
job_name = models.CharField(max_length=50, default='New Job')
client = models.ForeignKey(Client, on_delete=models.CASCADE)
job_code = models.CharField(max_length=15, unique=True,)
def get_job_code(self):
'''
I only want this to run once
Format abcMMnnYYYY
'''
jc = ''
prefix = self.client.job_code_prefix
month = str(str(self.job_date).split('-')[1])
identifier = len(Job.objects.filter(job_date__contains = f'-{month}-',
client__job_code_prefix = prefix)) + 2
year = str(str(self.job_date).split('-')[0])
jc = f'{prefix}{month}{identifier:02d}{year}'
return jc
#property
def total_cost(self):
all_costs = Cost.objects.filter(job__job_code = self.job_code)
total = 0
if all_costs:
for cost in all_costs:
total += cost.amount
return total
# Is there a way to add something like the flags in the commented-out code here?
def save(self, *args, **kwargs):
# if not self.job_code_fixed:
if self.job_code != self.get_job_code():
self.job_code = self.get_job_code()
# self.job_code_fixed = True
super().save(*args, **kwargs)
costsheet.py:
class costsheetView(ListView):
template_name = "main_app/costsheet.html"
form_class = CostForm
model = Cost
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
current_job_code = self.kwargs['job_code']
currentJob = Job.objects.get(job_code=current_job_code)
return context
def get(self, request, *args, **kwargs):
cost_form = self.form_class()
current_job_code = self.kwargs['job_code']
currentJob = Job.objects.get(job_code=current_job_code)
all_costs = Cost.objects.filter(job__job_code = current_job_code)
return render(request, self.template_name, {'cost_form':cost_form, 'currentJob':currentJob,'all_costs':all_costs})
def post(self, request, *args, **kwargs):
cost_form = self.form_class(request.POST)
current_job_code = self.kwargs['job_code']
currentJob = Job.objects.get(job_code=current_job_code)
messages = []
errors = ''
if cost_form.is_valid():
instance = cost_form.save()
instance.job = currentJob
instance.save()
currentJob.vendors.add(instance.vendor)
currentJob.save()
messages.append(f'cost added, job date: {currentJob.job_date}')
else:
print('oops')
print(cost_form.errors)
errors = cost_form.errors
all_costs = Cost.objects.filter(job__job_code = current_job_code)
return render(request, self.template_name, {'cost_form':cost_form,
'currentJob':currentJob,
'errors':errors,
'messages':messages,
'all_costs':all_costs,
})
Lastly, in the save() method I know I could do something like
if job_code != get_job_code():
job_code = get_job_code()
..but the job 'month' often changes throughout the life of the job, and if I run get_job_code() after the month changes then the job code will change again, which is undesirable.
A possible solution is to add an additional flag field, job_code_fixed, to the Job model. The job_code should only be generated once when the Job object is created, and not on subsequent saves. This can be achieved by setting job_code_fixed to True after the job_code is generated in the save method, and only generating the job_code if the job_code_fixed is False.
Here is an updated version of the code:
class Job(models.Model):
job_name = models.CharField(max_length=50, default='New Job')
client = models.ForeignKey(Client, on_delete=models.CASCADE)
job_code = models.CharField(max_length=15, unique=True,)
job_code_fixed = models.BooleanField(default=False)
def get_job_code(self):
'''
I only want this to run once
Format abcMMnnYYYY
'''
jc = ''
prefix = self.client.job_code_prefix
month = str(str(self.job_date).split('-')[1])
identifier = len(Job.objects.filter(job_date__contains = f'-{month}-',
client__job_code_prefix = prefix)) + 2
year = str(str(self.job_date).split('-')[0])
jc = f'{prefix}{month}{identifier:02d}{year}'
return jc
#property
def total_cost(self):
all_costs = Cost.objects.filter(job__job_code = self.job_code)
total = 0
if all_costs:
for cost in all_costs:
total += cost.amount
return total
def save(self, *args, **kwargs):
if not self.job_code_fixed:
self.job_code = self.get_job_code()
self.job_code_fixed = True
super().save(*args, **kwargs)
By adding the job_code_fixed flag, the job_code will only be generated once and never changed, solving the problem with changing job codes causing uniqueness and URL errors.
models.py -- there i create leave_links 10g field and want calculate him like substract by_projects_10g with on_facts_10g
class KT(models.Model):
by_projects_10g = models.CharField(max_length=255)
by_projects_100g = models.CharField(max_length=255)enter code here
on_facts_10g = models.CharField(max_length=255)
on_facts_100g = models.CharField(max_length=255)
#now I want do like this, but an error comes out
leave_links_10g = models.IntegerField(default=0)
def calculate_leave_links(a,b):
leave_links_10g = a -b
return leave_links_10g
def query_links(self):
calculate_leave_links(self.by_projects_10g, self.on_facts_10g)
#####views.py
def index(request):
KT_links = KT.objects.all().values()
template = loader.get_template('index.html')
context = {
'KT_links': KT_links,
}
return HttpResponse(template.render(context, request))
if you don't need to do db query on field leave_links_10g i sugest use #property:
#property
def leave_links_10g(self):
try:
return int(self.by_projects_10g) - int(elf.on_facts_10g)
except ValueError:
return 0
you can acces it like normal field e.g.:
kt_object.leave_links_10g
but if you want to do some db operations like filter or order_by you need to override save method of model KT:
def save(self, *args, **kwargs):
try:
self.leave_links_10g = int(self.by_projects_10g) - int(elf.on_facts_10g)
except ValueError:
self.leave_links_10g = 0
super().save(*args, **kwargs) # Call the "real" save() method.
I am trying to pass logged in user to form that i would like to save.
forms.py
class SpotForm(ModelForm):
def __init__(self, *args, **kwargs):
super(SpotForm, self).__init__(*args, **kwargs)
self.fields['gross_weight'].widget = forms.NumberInput(attrs={'min':0})
self.fields['volume'].widget = forms.NumberInput(attrs={'min': 0})
class Meta:
model = Spot
fields = [
'gross_weight','volume','origin_country','origin_port',
'dest_country','dest_port','ship_week','requestor'
]
models.py
class Stakeholder(models.Model):
user = models.OneToOneField(User,null=True,blank=True,on_delete=models.CASCADE)
company_name = models.CharField(max_length=15)
mail = models.CharField(max_length=40)
def __str__(self):
return self.mail
class Spot(models.Model):
STATUSES = (
('Open','Open'),
('Closed','Closed')
)
gross_weight = models.FloatField(null=False,default=0,validators=[MinValueValidator(0)])
volume = models.FloatField(null=False,default=0,validators=[MinValueValidator(0)])
origin_country = models.CharField(
validators=[RegexValidator(regex='[A-Z]{2}', message='Country code is two letters')], max_length=2,null=True)
origin_port = models.CharField(
validators=[RegexValidator(regex='[A-Z]{3}', message='Port code is three letters')], max_length=3,null=True)
dest_country = models.CharField(
validators=[RegexValidator(regex='[A-Z]{2}', message='Country code is two letters')], max_length=2,null=True)
dest_port = models.CharField(
validators=[RegexValidator(regex='[A-Z]{3}', message='Port code is three letters')], max_length=3,null=True)
time_registered = models.DateField(default=timezone.now)
spot_status = models.CharField(max_length=6,default='Open', choices=STATUSES)
ship_week = models.CharField(max_length=2,null=True)
requestor = models.ForeignKey(Stakeholder,null = True,on_delete=models.CASCADE)
def __str__(self):
return self.origin_country + self.origin_port + '-' + self.dest_country +self.dest_port + '-' + self.ship_week
views.py
def register_spot(request):
my_user = Stakeholder.objects.get(user=request.user)
form = SpotForm()
if request.method =='POST':
print("print",request.POST)
form = SpotForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
print(form.errors)
context = {'form': form}
return render(request, 'spotrequesting/register_spot.html', context)
When i submit the form i am getting an error in command prompt stating "This field is required" for "requestor". After that - dropdown list for this field come up on screen and i can select out of two registered users i have. But even selecting something from this list and again submitting the form is giving me the same error.
Checking "my_user" variable - it is showing me that i am logged in.
Is there a way to pass to "requestor" field currently logged in user?
I was able to get the form saved only by deleting "requestor" from "fields" in SpotForm (which gave me "None" in the end for this field in database) but that's not the desired outcome.
Any suggestion would be highly appreciated.
You are not really passing the stakeholder instance to the requestor field in the form are you? So you will have to do:
form = SpotForm(requestor = my_user)
I am trying to create a dynamic choice field. I have a view that creates a list of tuples. The first value of the tuple is the primary key of the object ServiceWriter while the second value is the name of the ServiceWriter. The list then gets passed into the form class. When I make the selection and submit the page the form is decided to be not valid and the following form error is printed in the shell: "Select a valid choice. (First value of tuple. ie 1,2,3..) is not one of the available choices."
forms.py
class CreateAdvancedRO(forms.Form):
service_writer = forms.ChoiceField()
def __init__(self, writer_choices, *args, **kwargs):
super(CreateAdvancedRO, self).__init__(*args, **kwargs)
self.fields['service_writer'].choices = writer_choices
self.helper = FormHelper()
self.helper.form_id = 'id-create-advanced-ro'
self.helper.form_method = 'post'
self.helper.add_input(Submit('submit', 'Open Repair Order'))
Note: I am not using a ModelForm.
views.py
class CreateAdvancedRO(View):
form_class = CreateAdvancedRO
writer_form = CreateServiceWriter
add_line_form = AddJobLine
def post(self, request):
writer_choices = []
form = self.form_class(writer_choices, request.POST)
print(form.errors)
if form.is_valid():
'''Do something'''
else:
writer_choices = []
try:
writers = ServiceWriter.objects.filter(user=request.user)
for writer in writers:
writer_choices.append((str(writer.id), writer.name))
except ObjectDoesNotExist:
pass
form = self.form_class(writer_choices, request.POST)
writer_form = self.writer_form()
add_line_form = self.add_line_form()
return render(request, 'free/advanced_create.html', {'form': form, 'writer_form': wri
'add_line_form': add_line_form})
I have tried both of the following in the view:
writer_choices.append((str(writer.id), writer.name)) and
writer_choices.append((writer.id, writer.name))
Here is the ServiceWriter model, just in case.
class ServiceWriter(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=20, blank=False)
def __str__(self):
return str(self.name)
Any thoughts?
Thanks for the help.
It looks like you're trying to validate the form against an empty list of choices. Have you tried populating writer_choices before instantiating or attempting to validate the form?
I have my model as this:
class Event(models.Model):
EventId = models.UUIDField(primary_key=True)
Winner = models.ForeignKey('Participant', on_delete=None)
class Participant(models.Model):
ID = models.UUIDField(primary_key=True)
Name = models.CharField()
I am trying to update an existing instance of the Event object using this in form.py
class UpdateWinner(ModelForm):
def __init__(self, *args, **kwargs):
e = kwargs.pop('e', '')
super(UpdateWinner, self).__init__(*args, **kwargs)
self.fields['Winner'] = forms.ModelChoiceField(queryset=e))
class Meta:
model = Event
fields = '__all__'
and in views.py
def update_winner(request, event_id):
if request.method == 'POST':
form = UpdateWinner(request.POST, instance=Event.objects.get(EventId=event_id))
if form.is_valid():
else:
event_par = Participant.objects.filter(some query)
form = UpdateWinner(instance=event, e=event_par)
I did check by printing the eventid, correct value is getting passed. but for some reason Winner field is causing some error with the form.is_valid() function and I am getting an error "'str' object has no attribute 'model'". Can anyone help me out here
Since you don't provide an e kwarg when handling POST requests in your view, your custom __init__ function sets e = ''. This causes the error when you go to define the queryset - that empty string has no attribute model. Try:
class UpdateWinner(ModelForm):
def __init__(self, *args, **kwargs):
e = kwargs.pop('e', None)
super(UpdateWinner, self).__init__(*args, **kwargs)
if e is not None:
self.fields['Winner'] = forms.ModelChoiceField(queryset=e))
The error comes from using that line:
e = kwargs.pop('e', '')
This means if the key e is not in kwargs return ' '. Then you use it there:
self.fields['Winner'] = forms.ModelChoiceField(queryset=e))
Which result in an empty queryset.