CSRF-токен отсутствует или неверен - использование автозаполнения в Django

Столкнулся с проблемой CSRF_Token missing or incorrect в моем Django-app, не совсем понимаю в чем проблема, так как я включил {% csrf_token %} во все возможные формы, выводимые моим шаблоном. Я подозреваю, что это может быть связано с ajax запросами, которые выполняются внутри формы для получения имен областей и прочего, может кто-нибудь подскажет мне, в чем проблема. Я использую autocomplete-light для получения некоторых данных из моей БД, не знаю, может ли это играть роль в этом. Я пробовал искать в интернете, но не нашел решения, которое бы подходило к моей проблеме.

Views.py

Class BreedAutocomplete(autocomplete.Select2QuerySetView):

    def get_queryset(self):

        if not self.request.user.is_authenticated:
            return DogBreeds.objects.none()

        qs = DogBreeds.objects.all()

        if self.q:
            qs = qs.filter(name__istartswith=self.q)

        return qs


class AdListTakeMyDog(generic.ListView):
    model = Advertisement
    context_object_name = 'ads'
    template_name = 'core/advertisement_list_take.html'

    def get_queryset(self):
        queryset = Advertisement.objects.filter(is_offering_own_dog=True)
        return queryset


class AdListGetMeADog(generic.ListView):
    model = Advertisement
    context_object_name = 'ads'
    template_name = 'core/advertisement_list_get.html'

    def get_queryset(self):
        queryset = Advertisement.objects.filter(is_offering_own_dog=False)
        return queryset


class NewAdTakeMyDog(CreateView):
    model = Advertisement
    form_class = NewAdTakeMyDogForm
    success_url = reverse_lazy('view_ads_take_my_dog')
    template_name = 'core/advertisement_form_take.html'

    def form_valid(self, form):
        form.instance.author = self.request.user
        form.instance.is_offering_own_dog = True
        return super().form_valid(form)


class NewAdGetMeADog(CreateView):
    model = Advertisement
    form_class = NewAdGetMeADogForm
    success_url = reverse_lazy('ad_changelist')
    template_name = 'core/advertisement_form_get.html'

    def form_valid(self, form):
        form.instance.author = self.request.user
        form.instance.is_offering_own_dog = False
        return super().form_valid(form)

advertisement_create - TEMPLATE

forms.py

class NewAdTakeMyDogForm(forms.ModelForm):

    breed = forms.ModelChoiceField(
        queryset=DogBreeds.objects.all(),
        widget=autocomplete.ModelSelect2(url='breed-autocomplete')
    )

    class Meta:
        model = Advertisement
        fields = ('province', 'municipality', 'area', 'title', 'description', 'days_per_week', 'size_offered', 'breed', 'image1', 'image2', 'image3')

    def __init__(self, *args, **kwargs):
        super(NewAdTakeMyDogForm, self).__init__(*args, **kwargs)
        self.fields['municipality'].queryset = Municipality.objects.none()
        self.fields['area'].queryset = Area.objects.none()
        self.fields['area'].required = False

        if 'province' in self.data:
            try:
                # Set municipality queryset
                province_id = int(self.data.get('province'))
                self.fields['municipality'].queryset = Municipality.objects.filter(province_id=province_id).order_by('name')
            
                # Set area queryset
                municipality_id = int(self.data.get('municipality'))
                self.fields['area'].queryset = Area.objects.filter(municipality_id=municipality_id).order_by('name')
                

            except (ValueError, TypeError):
                pass # invalid input from the client; ignore and fallback to empty Municipality/Area queryset
            

Ваш AJAX-запрос не содержит CSRF-токена. Поэтому срабатывает защита Django от подделки межсайтовых запросов.

Django документация подробно объясняет, как получить CSRF-токен при отправке AJAX POST запроса и как включить его в заголовки вашего запроса.

Ошибка заключалась в том, что я смотрел не на тот шаблон, у меня несколько шаблонов с наследованием, и я их перепутал, поэтому я думал, что представляю CSRF токен в форме, но это было сделано в шаблоне, который не использовался. Урок усвоен - имейте один базовый шаблон, с которого вы начинаете, и используйте блоки только для основного кода, который меняется между базовыми шаблонами.

Вернуться на верх