如何通过 AJAX POST Django 内联带有图像的表单集

How to POST Django Inline Formset with images via AJAX

我正在尝试通过 Ajax:

处理带图像的内联表单集

forms.py

class UserDogCreateForm(forms.ModelForm):
    class Meta:
        model = UserDog
        fields = ['name', 'breed', 'gender']


class UserDogImageCreateForm(forms.ModelForm):
    class Meta:
        model = UserDogImage
        fields = ['image', 'dog']
        labels = {'image': ''}


UserDogCreateFormSet = forms.inlineformset_factory(
    UserDog,
    UserDogImage,
    form=UserDogImageCreateForm,
    extra=3,
    can_delete=False,
    can_order=False,
)

views.py

class UserDogCreateView(LoginRequiredMixin, CreateView):
    model = UserDog
    form_class = UserDogCreateForm

    def get_context_data(self, **kwargs):
        context = super(UserDogCreateView, self).get_context_data(**kwargs)
        if self.request.POST:
            context['dog_image_inlines'] = UserDogCreateFormSet(self.request.POST, self.request.FILES)
        else:
            context['dog_image_inlines'] = UserDogCreateFormSet()
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        inlines = context['dog_image_inlines']
        with transaction.atomic():
            if inlines.is_valid():
                form.instance.user = self.request.user
                self.object = form.save()
                inlines.instance = self.object
                inlines.save()
                user_dogs = UserDog.objects.filter(user=self.request.user)
                return JsonResponse({'form_is_valid': True, 'user_dogs': serializers.serialize('json', user_dogs)})
            else:
                return JsonResponse({'form_is_valid': False})

    def form_invalid(self, form):
        return JsonResponse({'form_is_valid': False})

.html

<form id="dog-create-form" enctype="multipart/form-data" action="{% url 'dog-create' %}" method="post">
    {% csrf_token %}
    {{ form }}
    {{ dog_image_inlines.as_p }}
    <button type="submit">Submit</button>
</form>

.js

var dogCreateForm = $('#dog-create-form');
dogCreateForm.submit(function(e){
    e.preventDefault();
    var data = new dogCreateForm.serialize();
    console.log(data);
    $.ajax({
        url: '/accounts/dog-create/',
        type: 'post',
        dataType: 'json',
        data: data,
        success: function(data) {
            if (data.form_is_valid) {
                console.log('Dog created!');  // <-- This is just a placeholder for now
            } else {
                console.log('Dog not created!')
            }
        },
    });
})

提交 UserDog 数据后保存,但没有图像保存在 UserDogImage 中 forms.py 和 views.py 似乎一切正常。

我也试过了

var data = new FormData(dogCreateForm);

但它给出 403,因为由于某种原因它在 FormData 中看不到 csrftokenmiddleware

如果您遇到同样的问题,只需像这样使用 FormData:

.js

var dogCreateForm = $('#dog-create-form');
dogCreateForm.submit(function(e){
    e.preventDefault();
    var data = new FormData(this);
    $.ajax({
        url: '/accounts/dog-create/',
        type: 'post',
        dataType: 'json',
        data: data,
        processData: false,
        contentType: false,
        success: function(data) {
            if (data.form_is_valid) {
                console.log('Dog created!');  // <-- This is just a placeholder for now for testing
            } else {
                console.log('Dog not created!')
            }
        },
    });
})