I have 2 models:
models.py:
class Item(models.Model):
name = models.CharField(max_length=100)
price = models.FloatField(max_length=20)
shelfLife = models.BooleanField()
def __str__(self):
return self.name
#property
def shL(self):
temp = "Doesnt' have shelf life"
if(self.shelfLife):
temp = "Does have sehlf life"
return temp
class Order(models.Model):
num = models.CharField(max_length=20)
date = models.DateField()
items = models.ManyToManyField(Item)
def __str__(self):
return self.num
according to this doc I can do:
views.py:
elif request.method == "POST":
list_items = request.POST.getlist('arr[]') # get list of items
order_num = request.POST.getlist('o_n') # get order num
order_date = request.POST.getlist('o_d') # get order date
order = Order(num=order_num[0], date=order_date[0])
order.save()
for i in range(len(list_items)):
item_name = str(list_items[i])
item = Item.objects.filter(name=item_name)
order.items.add(item)
To fetch each item that I need, I loop through the list_items list of strings and filter each object request by this string and then just add the item to the many-to-many field of the order model.
In addition, when I fetch
item = Item.objects.filter(name="Salad")
the returned QuerySet is not empty, however, if I pass a string variable to the name filter it returns an empty QuerySet.
I would appreciate any help!
Thanks
EDIT:
As #Willem Van Onsem sudjested I chaned my views.py to:
elif request.method == "POST":
list_items = request.POST.getlist('arr[]') # get list of items
order_num = request.POST.getlist('o_n') # get order num
order_date = request.POST.getlist('o_d') # get order date
order = Order(num=order_num[0], date=order_date[0])
order.save()
items = Item.objects.filter(name__in=list_items)
order.items.add(*items)
However, I still get a QuerySet items as an empty QuerySet.
I have checked the request variable list_tems and it is a list of strings (it's not empty).
I tested it by creating an array of Strings
arr=["Salad", "Chocolate"]
and paste it as a filter
items = Item.objects.filter(name__in=arr)
order.items.add(*items)
to the QuerySet and it works - QuerySet object items is not empty and it writes the right data to the DB.
index.html:
$(document).on('click','.btn-create-order',function(){
$.ajax({
method: "GET",
contentType: "application/json",
url: "{% url 'order-items api' %}",
success: function(data){
var index = 1;
data.forEach(element => {
$('#multyItemSelect').append("<option value='" + index + "' id='" +index+ "'> "+ element['fields'].name+"</option>")
index++;
});
},
error: function(jqXHR, textStatus, errorThrown){}
})
})
$('.order-new-submit').click(function(){
var order_num = $('#InputNumber').val()
var order_date = $('#InputDate').val()
var item_selected = $('#multyItemSelect').val() // number
var arr = [] // arr for the item names
var index = 0;
item_selected.forEach(e => {
arr[index] = $('#' + e).html()
index++
});
console.log(order_date)
// DEBUGIN
// arr.forEach(e => {
// console.log(e)
// });
// END DEBUGIN
$.ajax({
method: "POST",
url: "{% url 'order-items api' %}",
data: {'arr[]': arr,
'o_n' : order_num,
'o_d' : order_date},
success: function(data){
},
error: function(jqXHR, textStatus, errorThrown){}
})
})
Thanks to #Willem Van Onsem the issue has been found:
print(list_items)
prints values with space at the beginning:
[' Salad', ' Beef Stake ', ' Chocolate']
item in order.items.add(…) needs to be a model object, or the primary key of that model, but not a queryset. You can however make use of iterable unpacking to pass the items wrapped in the QuerySet as individual parameters:
for i in range(len(list_items)):
item_name = str(list_items[i])
items = Item.objects.filter(name=item_name)
order.items.add(*items) # ← with an asterisk (*)
You can boost efficiency by fetching all the Items in one query with:
items = Item.objects.filter(name__in=[str(x) for x in list_items])
order.items.add(*items)
Related
I have a project with a model called "List," and a model called "ListItem." There are multiple list items to each list. Here's what I'd like to do. I'd like the user to be able to create a new list with as many items as they deem necessary on one form.
Here's the logic I have so far:
models.py:
class List(models.Model):
team = models.ForeignKey(Team, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class ListItem(models.Model):
team_list = models.ForeignKey(List, on_delete=models.CASCADE)
content = models.TextField()
index = models.IntegerField()
def __str__(self):
return f"{self.team_list} [{self.index}]"
forms.py:
class NewListForm(forms.ModelForm):
name = forms.CharField(max_length=50, label='Card Name')
team = forms.ModelChoiceField(queryset=models.Team.objects.all())
class Meta:
model = models.List
fields = ['name', 'team']
class NewListItemForm(forms.ModelForm):
content = forms.CharField(widget=forms.Textarea,
label='Item', required=True)
class Meta:
model = models.ListItem
fields = ['content']
views.py:
def new_list(request):
context = {
'title': 'New List',
'list_form': NewListForm,
'list_item_form': NewListItemForm,
}
if request.method == 'POST':
list_form = NewListForm(request.POST)
list_item_form = NewListItemForm(request.POST)
if list_form.is_valid() and list_item_form.is_valid():
list_instance = list_form.save()
list_item_instance = list_item_form.save(commit=False)
list_item_instance.team_list = list_instance
list_item_instance.index = 1
list_item_instance.save()
messages.success(request, "List has been created!")
return redirect('home')
else:
messages.error(request, "That list name is already taken")
return render(request, 'lists/new_list.html', context)
This works for creating 1 list and just 1 item. Ultimately, I'd like the user to be able to add as many additional list item forms as is necessary AND have the "index" field of each item on that list increment by 1 with each new list item instance.
Is there some way to loop through each instance of a repeated form and save a unique instance in my db an indefinite number of times?
I don't think you need to increment the index yourself, django should increment it automatically. I used formset_factory and javascript on my template to have the ability to add fields to the form dynamically. I am not very familiar with django or javascript (I'm very early in the learning process), but this is how I got it to work in my case:
models.py
class Instructors(models.Model):
instructors = models.CharField(max_length=60)
injury = models.ForeignKey("Injury", on_delete=models.CASCADE)
forms.py
class InstructorForm(forms.Form):
instructor = forms.CharField(max_length=60, required=False)
InstructorFormset = formset_factory(InstructorForm, extra=1)
views.py (relevant section)
...
formset = InstructorFormset(request.POST)
if formset.is_valid()
for form in formset:
if form.cleaned_data:
instructor = Instructors(
instructors=form.cleaned_data["instructor"],
injury=injury,
)
instructor.save()
...
context = {"formset":formset}
template.html
{{ formset.management_form }}
{% for form in formset %}
<div class="row form-row spacer">
{{ form.instructor }}
<div class="input-group-append">
...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type='text/javascript'>
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
console.log(newElement);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function() {
var name = $(this).attr('name');
if (name != undefined) {
console.log(name);
console.log(total);
var name = name.replace('-' + (total-1) + '-', '-' + total + '-');
console.log("next");
};
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function() {
var forValue = $(this).attr('for');
if (forValue) {
forValue = forValue.replace('-' + (total-1) + '-', '-' + total + '-');
$(this).attr({'for': forValue});
}
});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('-');
return false;
}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;
}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;
});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;
});
</script>
I don't remember where I got the js code, but I did not write it and can't take credit for it. Hopefully you have a better understanding than I do, but it works for me as is.
I have a function that makes a queryset when data from my frontend is posted.
This viewset is using a serializer of combined models.
On my index page on the fronted I have a treeview filter and this view loads the query to
a config page. I need to access the event id's after this query is made to be passed to a separate task on the backend for polling.
However I cannot access the data in this function. How would I get retrieve this query and filter on the data? right now I can't print the queryset to see its structure.
Edit:
I can see the response payload now and the structure is as follows
[{"id":395,"event":{"id":175,"start_time":"28-10-20","sport_id":"9","event_id":"1576232279920003","event_name":"Botic Van de Zandschulp vs Benjamin Bonzi","status":"open"},"market":{"id":198,"market_id":"1576232286670003","market_name":"Moneyline","status":"open","volume":50.4951,"is_ip":"False","event":175},"bettriggers":null,"stakes":null,"userstakes":null,"order":null,"runner_id":"1576232286740003","name":"Botic Van de Zandschulp","back_odds":1.62893,"lay_odds":1.68028},{"id":396,"event":{"id":175,"start_time":"28-10-20","sport_id":"9","event_id":"1576232279920003","event_name":"Botic Van de Zandschulp vs Benjamin Bonzi","status":"open"},"market":{"id":198,"market_id":"1576232286670003","market_name":"Moneyline","status":"open","volume":50.4951,"is_ip":"False","event":175},"bettriggers":null,"stakes":null,"userstakes":null,"order":null,"runner_id":"1576232286780103","name":"Benjamin Bonzi","back_odds":2.47,"lay_odds":2.59}]
class CombinedViewSet(mixins.ListModelMixin,
mixins.DestroyModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
permission_classes = [IsMeOrReadOnly]
queryset = Runner.objects.all()
serializer_class = CombinedSerializer
#action(detail=False, methods=['POST','GET])
def loaditem(self, request):
keys = request.data['keys']
queryset = []
for xx in keys:
if xx['time_key'] is None:
if xx['event_key'] is None:
queryset.extend(Runner.objects.filter(event__sport_id=xx['sport_key']))
else:
queryset.extend(Runner.objects.filter(event__event_id=xx['event_key']))
else:
date_str = xx['time_key']
datetime_obj = datetime.datetime.strptime(date_str, '%d-%m-%y')
queryset.extend(Runner.objects.filter(event__start_time__date=datetime_obj, event__sport_id=xx['sport_key']))
serializer_class = CombinedSerializer(queryset, many=True)
return Response(serializer_class.data)
What my end goal is to pass in the filtered list of event_id's from load item function to a backend celery task
#shared_task(bind=True, base=QueueOnce, once={'graceful': True})
def get_events(self):
api = get_client()
sports = api.reference_data.get_sports()
logger.warning(f'GET EVENTS task has been called now')
events = api.market_data.get_selected_events(event_ids=['2323','34343','1576232279920003','etc'])
This is what my serializer looks like
class CombinedSerializer(serializers.ModelSerializer):
event = EventSerializer()
market = MarketSerializer()
bettriggers = BetTriggersSerializer()
stakes = StakesSerializer()
userstakes = UserStakesSerializer()
order = OrderStakesSerializer()
class Meta:
model = Runner
fields= '__all__'
Frontend code for posting data
load_item: function (event) {
if(this.value == null) return;
var len = this.value.length;
var req_key = [];
for (var x=0; x<len; x++) {
var str = ''+this.value[x];
var tmp_arr = str.split('#');
var sport_key = null;
var time_key = null;
var event_key = null;
switch(tmp_arr.length) {
case 1:
sport_key = tmp_arr[0];
break;
case 2:
event_key = tmp_arr[1];
break;
case 3:
time_key = tmp_arr[2];
sport_key = tmp_arr[1];
break;
}
req_key.push({sport_key:sport_key, event_key:event_key, time_key:time_key});
}
var vobj = this
this.$axios.post('/api/combined/loaditem/', {
keys : req_key
})
.then(function (response) {
vobj.$store.dispatch('load_runner', response.data)
vobj.$router.push('/configuration')
})
.catch(function (error) {
//currentObj.output = error;
console.log(error)
});
},
Im new in Django,
I'm using xhtml2pdf for rendering data objects from template to PDF file , and i want to allow users to render only checked objects by checkboxes into pdf, is there anyway to filter that in Django ?
Thanks
views.py :
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode('ISO-8859-1')), result, link_callback=link_callback)
if pdf.err:
return HttpResponse('Error')
return HttpResponse(result.getvalue(), content_type='application/pdf')
class ViewPDF(View):
#method_decorator(login_required(login_url='livraison:login_page'))
def get(self, request, *args, **kwargs):
checked_objects = [i dont know how to get them]
queryset = Livraison.objects.filter(id__in=[checked_objects]) # i want something does that
data = {
'livraisons' : queryset,
'now' : f'Livraisons-{date.today()}'
}
pdf = render_to_pdf('pdf_template.html', data)
return HttpResponse(pdf, content_type='application/pdf')
use forms to get user data.
class LivraisonSelectForm(forms.Form):
livraison = forms.ModelChoiceField(label='select', queryset=Livraison.objects.all(), widget=forms.CheckboxInput())
then use it in your view:
class ViewPDF(FormView):
form_class = LivraisonSelectForm
template_name = 'path_to_template_with_html_to_filter_data'
#method_decorator(login_required(login_url='livraison:login_page'))
def form_valid(self, form):
checked_objects = form.cleaned_data.get('livraison', [])
queryset = Livraison.objects.filter(id__in=checked_objects) # i want something does that
data = {
'livraisons' : queryset,
'now' : f'Livraisons-{date.today()}'
}
pdf = render_to_pdf('pdf_template.html', data)
return HttpResponse(pdf, content_type='application/pdf')
and don't forget to show this form in your html {{ form }}
**
UPDATE
**
I Found a solution , i used Ajax code to collect every selected object
// check selected objects (#pdf is the id of the button which gonna generate the pdf file)
$('#pdf').click(function () {
var id = [];
$(':checkbox:checked').each(function (i) {
id[i] = $(this).val()
})
if (id.length === 0) {
alert('Please Select something..');
} else {
$.ajax({
url: '.',
method: 'GET',
data: {
id,
},
success: function (response) {
console.log('PDF is ready')
}
})
}
});
then i ad the variable into the view function to collect the selected objects and filter the queryset
myFunction.selected_ones = request.GET.getlist('id[]')
then filter queryset in the generated_pdf_func
queryset = MODEL.objects.filter(id__in=[x for x in myFunction.selected_ones if x != '0'])
NOTE : <if x != '0'> is important in case you want to select all because it returns 0 and you don't have any id = 0 in the DB
I tried this code to save my JSON data to my model that is Mvouchar. But getting this error. I easily get data through cmd but I tried to save this in my model then I get the error, why this happens, I think am doing some minor mistake but can't catch please help if u get my problem
#views.py
#csrf_exempt
def jsdata(request):
table_data = json.loads(request.POST.get('MyData'))
print(table_data)
for data in table_data:
b_no = request.POST['billno']
b_details = request.POST['billdetails']
at = request.POST['amount2']
record = Mvouchar(bill_no = data.b_no, bill_details = data.b_details,am=data.at)
record.save()
return render(request, 'cheque/mvouchar.html', {'msg': 'Data Saved.'})
#models.py
class Mvouchar(models.Model):
related = models.ForeignKey(Signs, on_delete=models.CASCADE, null=True, blank=True)
bill_no = models.CharField(max_length=80, null=True, blank=True)
bill_details = models.CharField(max_length=1000, null=True, blank=True)
am = models.CharField(max_length=30, null=True, blank=True)
vouchar_no = models.CharField(max_length=1000, null=True, blank=True)
#urls.py
url(r'jsondata/$', views.jsdata, name='jsondata'),
#script
<script>
$("#btnjson").click(function () {
var array1 = [];
$("tbody tr").each(function () {
var firstTableData = {};
firstTableData.BillNo = $(this).find('td').eq(0).text();
firstTableData.BillDetails = $(this).find('td').eq(1).text();
firstTableData.Amount = $(this).find('td').eq(2).text();
array1.push(firstTableData);
//}
});
alert(JSON.stringify(array1));
$.ajax({
type: "POST",
url: "/jsondata/",
dataType: 'json',
data: {MyData: JSON.stringify(array1)},
success: function(msg){
alert(msg);
}
});
return false;
} );
});
</script>
from django.http import JsonResponse
def jsdata(request):
table_data = json.loads(request.POST.get('MyData'))
# print(table_data)
r_data = {
'success': True,
}
for data in table_data:
# Since you are just creating objects you don't need to save created object in a variable.
try:
Mvouchar.objects.create(bill_no = data['BillNo'], bill_details=data['BillDetails'],at=data['Amount'])
except:
r_data['success'] = False
# IMO Views responding to ajax requests should send JsonResponse
if r_data['success']:
r_data['msg'] = 'Data Saved'
else:
r_data['msg'] = 'Not all Data Saved'
return JsonResponse(r_data)
This error probably occurs when the key not present in request data. By changing
b_no = request.POST['billno']
to
b_no = request.POST.get('BillNo').
solve throwing this exception. Even if data not present it returns None. Or can handle it by add try.except block.
try:
b_no = request.POST['billno']
except KeyError:
pass
And in your code, you call every dict key in lower case form and amount key as amount2. Change that to Amount
If your are storing data in table_data (table_data = request.POST.get('MyData')) then use table_data to store it in models.
Your data is in dictionary form so need to call values by its keys.
like -
#csrf_exempt
def jsdata(request):
table_data = json.loads(request.POST.get('MyData'))
print(table_data)
for data in table_data:
b_no = data.get('BillNo')
b_details = data.get('BillDetails')
at = data.get('Amount')
record = Mvouchar(bill_no = b_no , bill_details = b_details ,am=at )
record.save()
return render(request, 'cheque/mvouchar.html', {'msg': 'Data Saved.'})
Try this and tell me if any error occurs.
A KeyError is usually thrown when you look up a value for a key in a dictionary that does not exist. You could either provide a default value or check the existence of the key before you do the lookup.
request.POST.get('billno', 'default_value')
For more information about querying a dictionary with default values, see this helpful StackOverflow answer
The line above as such will not work, since there are other issues in this code besides the key not existing with only lowercase letters (see below).
Looking at the code I expect the key to not exist either because it has not been sent or because it may contain uppercase letters.
As it has been pointed out in the comments to your question, not only are you querying for billno (only lowercase letters) while the key you send has uppercase letters (BillNo), but you also embed it into another dictionary MyData - you need to change your query from request.POST['billno'] to data['BillNo'] (the same goes for all the other values you are trying to extract).
The correct query would thus look like this:
for data in table_data:
b_no = data['BillNo']
b_details = data['BillDetails']
at = data['Amount']
record = Mvouchar(bill_no = b_no, bill_details = b_details,am=at)
record.save()
I have a save method on my model which I would like to use to validate the fields (I did this in my views before but it was just messy!). I'm saving an object rather than a form because I was having some difficulties with the form validation.
I haven't used save methods before, but I assume they trigger when you use the .save() command? Mine isn't triggering at all... Also from what I understand a clean() method is run for forms when you use is_valid(), so isn't useful for me here?
Here is my view that saves an object using ajax
#login_required
def createtimesheet(request):
if request.method == "POST":
print "creating timesheet"
# Get the person from the previous view
person_object = request.session.get('person')
person = Person.objects.get(id=person_object)
# get the POST data
start_date = request.POST.get('datestart')
end_date = request.POST.get('dateend')
start_date_formatted = datetime.strptime(start_date, "%m/%d/%Y")
end_date_formatted = datetime.strptime(end_date, "%m/%d/%Y")
start_date_print = start_date_formatted.strftime("%B")[0:3] + ". " + start_date_formatted.strftime("%d") + ", " + start_date_formatted.strftime("%Y")
end_date_print = end_date_formatted.strftime("%B")[0:3] + ". " + end_date_formatted.strftime("%d") + ", " + end_date_formatted.strftime("%Y")
response_data = {}
# create our messages
message = ""
error = ""
todays_date = datetime.now()
print_date = todays_date.strftime("%A")
# now we can create the timesheet!
peach = TimeSheet(start_date=start_date_formatted, end_date=end_date_formatted, person_id=person)
# need an if valid.....?
peach.save()
message = "Created new timesheet"
response_data['startdate'] = start_date_print
response_data['enddate'] = end_date_print
response_data['status'] = peach.status
print response_data
context = {
"person": person,
"message": message,
"error": error,
"print_date": print_date,
"todays_date": todays_date,
}
return JsonResponse(response_data)
And here is where I have attempted to write a save method... I'm planning to have a much longer validation function to check if the dates fall on certain days, but for now I just want to get this to work.
class TimeSheet(models.Model):
O = "Open"
S = "Submitted"
A = "Approved"
R = "Needs review"
STATUS_CHOICES = (
(O, "Open"),
(S, "Submitted"),
(A, "Approved"),
(R, "Needs Reviewing"),
)
start_date = models.DateField()
end_date = models.DateField()
person_id = models.ForeignKey(Person)
status = models.CharField(max_length= 50, default="Open", choices=STATUS_CHOICES)
submitted_id = models.IntegerField(default=0)
approved_id = models.IntegerField(default=0)
submitted_date = models.DateTimeField(auto_now_add=True, blank=True)
approved_date = models.DateTimeField(auto_now_add=True, blank=True)
# def __str__(self):
# return self.id
def get_absolute_url(self):
return reverse('tande:timesheet', kwargs={'id': self.id})
def __init__(self, *args, **kwargs):
print "initiating a timesheet"
super(TimeSheet, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
print "something is trying to save!"
ok_to_continue = True
start_date = self.start_date
end_date = self.end_date
if ok_to_continue:
if end_date < start_date:
error = "Start date must be before end date"
ok_to_continue = False
if ok_to_continue:
super(TimeSheet, self).save(*args, **kwargs)
else:
print "def save did not work"
Thanks!
Edit: here is the ajax call
$( document ).ready(function() {
$('#timesheet-form').on('submit', function(event){
event.preventDefault();
console.log("add a timesheet");
createtimesheet();
});
function createtimesheet() {
console.log("create timesheet is working!")
$.ajax({
url : "{% url 'tande:createtimesheet' %}",
type: "POST",
data: { datestart : $('#start').val(), dateend : $('#end').val()},
success : function(json) {
$('#start').val('');
$('#end').val('');
console.log(json);
var html = '<tr><td>'+json.startdate+'</td><td>'+json.enddate+'</td><td>'+json.status+'</td><</tr>';
console.log("success");
// $('div#talk').html(html);
$('#timesheet-list').append(html);
console.log(html)
overlay();
},
error : function(xhr,errmsg,err) {
// $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
// " <a href='#' class='close'>×</a></div>"); // add the error to the dom
console.log("uh oh");
}
});
};
})
URLs:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^people/$', views.people, name='people'),
url(r'^people/create_person/$', views.create_person, name='create_person'),
url(r'^(?P<person_id>[0-9]+)/person/$', views.person, name='person' ),
url(r'^person/createtimesheet/$', views.createtimesheet, name='createtimesheet' ),
url(r'^(?P<timesheet_id>[0-9]+)/person/timesheet/$', views.timesheet, name='timesheet' ),
]
form id didn't match the id in the ajax call...
id in html is 'create-timesheet-form' and ajax was calling 'timesheet-form'
-.-