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 токен в форме, но это было сделано в шаблоне, который не использовался. Урок усвоен - имейте один базовый шаблон, с которого вы начинаете, и используйте блоки только для основного кода, который меняется между базовыми шаблонами.