0

I have an HTML view of a ModelForm where I'm trying to take a separate user input called scanner_input, run some code on it, and then replace request.post['product_id'] with the result from the code I just ran.

Everywhere I look, it says the same thing, that request.post objects can be made mutable by using .copy() and yet I get the following error message:

'SerialInstanceForm' object does not support item assignment

The error occurs in this line from my view:

post['product_id'] = scanner_input_list[i]

Here's my view:

def SerialMulti(request):
    if request.method == "POST":
        form = SerialInstanceForm(request.POST)
        if form.is_valid():
            scanner_input = request.POST['scanner_input']
            scanner_input_list = scanner_input.splitlines()

            for i in range(0, len(scanner_input_list)):
                post = SerialInstanceForm(request.POST.copy())
                post['product_id'] = scanner_input_list[i]
                post.save()

        return render(request, 'serial_multi.html', {'form': form})
    else:
        form = SerialInstanceForm()
    return render(request, 'serial_multi.html', {'form': form})

My model:

class ProductSerialInstance(models.Model):
    STATUS_CHOICES = (
        ('in_inventory', 'In Stock'),
        ('given_out', 'Given Out'),
        ('repair', 'Repair')
    )

    name = models.ForeignKey(ProductSerial)
    employee = models.ForeignKey(Employee, blank=True, null=True)
    it_dep = models.ForeignKey(ItDep)
    product_id = models.CharField(max_length=50)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft')
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.name

And my form:

class SerialInstanceForm(forms.ModelForm):
    # duplications = forms.IntegerField()
    class Meta:
        model = ProductSerialInstance
        fields = ['name','employee','it_dep','status']
Community
  • 1
  • 1
  • 1. That line's not in the code you've posted. 2. `post` isn't the `POST` copy, it's a `SerialInstanceForm`. 3. And `SerialInstanceForm` doesn't have a `product_id` attribute. – jonrsharpe May 06 '17 at 10:06
  • @jonrsharpe You're right, I added the wrong line by mistake. I've edited the question to be correct. Does product_id need to be in the form? Isn't it enough that it's in the model? The idea is, that rather than putting it in the form, I want a separate textfield, where you can enter multiple product id's, separated by newlines, after which I put these into a list and create database records for each product id in the list. Hope that makes sense. Thanks for your help! – Jakob Handberg Lystbæk May 06 '17 at 10:49
  • What are you actually trying to achieve? Give some examples with dummy data.. Also in your view apart from the "post" issue, you are just looping on the same data. Why would you do that..? – zaidfazil May 06 '17 at 10:53
  • @FazilZaid I want the user to be able to add multiple records that share the same data, but with different product id's. So the user might input `name="Magic Mouse"`, `employee="John"`, `it_dep="CPH"`, `status="On loan"` and then in a textfield the user puts `"abc \n def \n ghi \n"`. When the user submits, it takes that string, split it up on each `\n` and creates identical database records but with different product id's. – Jakob Handberg Lystbæk May 06 '17 at 11:04

1 Answers1

1

From what you said, I've edited your view according to what I think the way should be, I don't know if this work or not, but certainly help you understand some things.

You don't need to make request.POST mutable, for getting a data.

def SerialMulti(request):
    if request.method == "POST":
        form = SerialInstanceForm(request.POST)
        if form.is_valid():
            scanner_input = request.POST.get('scanner_input')
            scanner_input_list = scanner_input.splitlines()

            for i in range(0, len(scanner_input_list)):
                #edited here to make multiple instances save.
                post = ProductSerialInstance.objects.create(**form.cleaned_data)
                post.product_id = scanner_input[i]
                post.save()

        return render(request, 'serial_multi.html', {'form': form})
    else:
        form = SerialInstanceForm()
    return render(request, 'serial_multi.html', {'form': form})
zaidfazil
  • 9,017
  • 2
  • 24
  • 47