Home > database >  Django - TypeError __init__() missing 1 required positional argument when uploading a file
Django - TypeError __init__() missing 1 required positional argument when uploading a file

Time:01-17

I want to set an initial value "test" to the field name when I'm uploading a file with a Django. Here is what I tried in views.py:

class UploadFile(CreateView):
    form_class = UploadFileForm
    template_name = "tool/upload.html"
    success_url = reverse_lazy('tool:index')

    fields = ['file',]

    def get(self, request, *args, **kwargs):
        form = self.form_class()
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect(self.success_url)
        else:
            return render(request, self.template_name, {'form': form})

And in forms.py:

class UploadFileForm(forms.ModelForm):

    class Meta:
            model = CheckFile
            fields = ['file', ]

    def __init__(self, file, *args, **kwargs):
        file = kwargs.pop('file')
        super(UploadFileForm, self).__init__(*args, **kwargs)
        if file:
            self.fields['name'] = "test"

But I end up having the following error: TypeError: UploadFileForm.__init__() missing 1 required positional argument: 'file'

I don't understand why I keep having this error. Could you please help me?

Thanks!

Edit : here's the HTML form.

{% extends 'base.html' %}

{% block content %}

<h1>Enregistrer les tarifs</h1>
    <form method="POST">
        <p>
            {% csrf_token %}
            {{ form.as_p }}
        </p>
        <button type="submit">Save</button>
    </form>

{% endblock %}

CodePudding user response:

You are doing too much, the file = kwargs.pop('file') makes no sense: the data is passed as request.FILES and is passed to the ModelForm, your ModelForm can thus look like:

class UploadFileForm(forms.ModelForm):
    class Meta:
        model = CheckFile
        fields = ['file', ]

    # no __init__

The same for your view: Django will automatically create the form and pass the data accordingly. If you want to specify the name of the CheckFile, you can do that in the form_valid method:

class UploadFileView(CreateView):
    form_class = UploadFileForm
    template_name = "tool/upload.html"
    success_url = reverse_lazy('tool:index')
    
    def form_valid(self, form):
        form.instance.name = 'test'
        return super().form_valid(form)

If you are submitting files, you should specify enctype="multipart/form-data":

<form method="POST" enctype="multipart/form-data">
    <p>
        {% csrf_token %}
        {{ form.as_p }}
    </p>
    <button type="submit">Save</button>
</form>

and that's all that is necessary.

  •  Tags:  
  • Related