Я знаю, что могу использовать декораторы, такие как @login_required
и @permission_required()
, или заключить представление в функцию, такую как login_required()
, чтобы перенаправить пользователя для предоставления дополнительной информации (в этом случае войдите в систему). В случае успеха пользователь перенаправляется на URL, к которому он пытался получить доступ в первую очередь (автоматически с использованием логики ?next=/
в URL).
Теперь я хотел бы применить логику ?next=/
к другому случаю. Мой пользователь вошел в систему и хочет получить кусок на сайте. Чтобы успешно сделать это, он должен был предоставить свой адрес. В представлении я проверяю, все ли поля адреса не пусты. Если одно из полей не заполнено, я перенаправляю пользователя по умолчанию UpdateView
(форма). Если пользователь заполнил поля (нажимает кнопку отправки), я бы хотел перенаправить его на URL-адрес, с которого он пришел (пытаясь получить часть). Из-за этого перенаправления процесс проверки, если все поля адреса не пусты, начнется заново, и если это удастся, на этот раз часть будет востребована.
Как логика ?next=/
применяется в таком случае?
views.py
from django.views.generic import RedirectView
from django.http import QueryDict
class ClaimRedirectView(RedirectView):
REQUIRED_FIELDS = ['first_name', 'last_name', 'street', 'street_number', 'zip_code', 'state_province', 'location', 'country']
permanent = False
def get_redirect_url(self, *args, **kwargs):
claimant = get_object_or_404(Creator, user=self.request.user)
missing_fields = [fields.name for fields in claimant._meta.get_fields(include_hidden=False) if fields.name in self.REQUIRED_FIELDS and not getattr(claimant, fields.attname, None)]
if not missing_fields:
return reverse('my-claimed')
messages.info(self.request, 'Please fill in your complete address to proceed')
next = self.request.get_full_path()
path = reverse('creator-update', kwargs={'slug': claimant.slug})
#q = QueryDict('next=%s' % next)
q = 'next=' + next
return '%s?%s' % (path, q)
class CreatorUpdate(LoginRequiredMixin, UpdateView):
model = Creator
slug_field = 'slug'
fields = ['first_name', 'last_name', 'street', 'street_number', 'zip_code', 'location', 'state_province', 'country']
# these two methods only give access to the users own profile but not the others
def user_passes_test(self, request):
if request.user.is_authenticated:
self.object = self.get_object()
return self.object.user == request.user
return False
def dispatch(self, request, *args, **kwargs):
if not self.user_passes_test(request):
return redirect_to_login(request.get_full_path())
return super(CreatorUpdate, self).dispatch(request, *args, **kwargs)
urls.py
path('claim/<uuid:pk>', login_required(views.ClaimRedirectView.as_view()), name='claim')
path('creator/<slug:slug>/update/', views.CreatorUpdate.as_view(), name='creator-update')
creator_form.html
{% extends "base_generic.html" %}
{% block content %}
{% if messages %}
{% for message in messages %}
<p{% if message.tags %} class="{{ message.tags }}"{% endif %}><strong>{{ message }}</strong></p>
{% endfor %}
{% endif %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_ul }}
<input type="submit" value="Submit">
</form>
{% endblock %}
При реализации вышеупомянутого ClaimRedirectView
, как предложено @, я попадаю в форму, чтобы заполнить дополнительную информацию и увидеть правильный URL-адрес (имея следующую логику). Но при заполнении формы я не обращаюсь к следующей части URL. Может ли это быть как-то связано с самой формой (generic UpdateView
)?