I have a Model and would like to save data as a batch by using a textarea form in Django. The data shall be save line by line, which I am using splitlines(), each data is comma separated by split(","). I am operating the manipulation in the form_valid() function but I can't seem to get it right.
Only the last line is saved successfully.
forms.py
class DataForm(forms.ModelForm):
textarea_data = forms.CharField(widget=forms.Textarea)
class Meta:
model = Item
exclude = ('part_number','length','height','weight')
views.py
class InsertData(generic.CreateView):
model = Item
form_class = DataForm
def get_success_url(self):
return reverse('item_list')
def form_valid(self, form):
self.object = form.save(commit=False)
textarea_data = form.cleaned_data['textarea_data ']
data_line_list = textarea_data.splitlines()
for each_line in data_line_list:
each_line_list = each_line.split(",")
self.object.part_number = each_line_list[0]
self.object.length = each_line_list[1]
self.object.weight = each_line_list[2]
self.object.height = each_line_list[3]
self.object.save()
May I know where did I go wrong. Should the manipulation be done some where else?
CodePudding user response:
self.object.save()
keeps overwriting your object. You want to create separate db records from each line of your textarea input.
Better create a simple form forms.Form
for data entry instead of ModelForm.
Then on the its form_valid, iterate through the lines and create objects. Each iteration should create a new object and save.
You need to get rid of the textarea field as well.
If its a lot of data, it’s better to use bulk create function for performance.
CodePudding user response:
I found the solution after reading this https://stackoverflow.com/a/33027228/13152307 .
I should set the primary key to none at the beginning of each iteration.
for each_line in data_line_list:
self.object.pk = None #add this line
each_line_list = each_line.split(",")
self.object.part_number = each_line_list[0]
self.object.length = each_line_list[1]
self.object.weight = each_line_list[2]
self.object.height = each_line_list[3]
self.object.save()
I understand that it may not be a good way to do so, but at least it works now.