0

Возможно, я могу переусердствовать в этом, а может и нет. У меня есть форма регистрации, которую я хочу использовать на индексной странице и как отдельная форма. По какой-то причине отдельная форма работает просто отлично, но форма на индексной странице дает мне ошибку 403, когда она отправлена. Я буду использовать jQuery позже, но мне нужно, чтобы все работало без JavaScript.Django: Используйте тот же вид для обработки той же формы на двух отдельных страницах.

Оказывает ПОДПИСАТЬСЯ форму, похожие на Facebook страницу

# views.py snippet 
class IndexPageTemplateView(TemplateView): # index page(http://localhost) 
    template_name = 'fld/index.html' 

    def get(self, request, *args, **kwargs): 
    # prevent logged in users from accessing welcome page 
    if self.request.user.is_authenticated(): 
     return HttpResponse(reverse("member_homepage", args=some_args)) 
    else: 
     return render_to_response(self.template_name) 

# Account view 

class AccountCreateView(CreateView): # standalone(http://localhost/signup) 
     model = Account 
     form_class = CreateAccountForm 
     template_name = 'fld2/account_form' 
     success_url = 'thanks' 

    def get(self, request, *args, **kwargs): 
    # prevent logged in users from seeing this form 
    if self.request.user.is_authenticated(): 
     # get the username of logged in user 
     ... 
     # redirect to homepage 
     return HttpResponseRedirect(reverse('some_args', args=(args,))) 
    else: 
     # display form to non members 
     return render(request, self.template_name, {'form': self.get_form_class()}) 

    def form_valid(self, form): 
     clean = form.cleaned_data 
     form.instance = form.save() 
     if form.instance: 
      try: 
       # send email 
      except Account.DoesNotExist: 
      ... 
     return super(AccountCreateView, self).form_valid(form) 

Я буквально используя те же самые точные формы с атрибутами разных действий. Я попытался заменить значения атрибутов, используя те же значения атрибутов и не используя значения атрибутов. Кажется, я не могу получить доступ к моему представлению со страницы индекса, даже когда я его жестко кодирую, я получаю ошибку 403. В основном посетитель должен иметь возможность зарегистрироваться на главной странице (например, Facebook) или на странице регистрации (например, Twitter). Я думаю, что мне, возможно, придется использовать сигналы, чтобы сделать эту работу.

http://localhost/

<!--index.html snippet--> 
<form action="{% url "create_account" %}" method="post">{% csrf_token %} 
    <input name="username" type="text" required> 
    <input name="password" type="password" required> 
    <input name="email" type="email" required> 
    <input name="signup1" type="submit" value="Create account"> 
</form> 

http://localhost/signup

<!--account_form.html--> 
<form action="." method="post">{% csrf_token %} 
    <input name="username" type="text" required> 
    <input name="password" type="password" required> 
    <input name="email" type="email" required>  
    <input name="signup2" value="Create account" type="submit"> 
</form> 

Основные urls.py фрагмент

url(
    regex=r'^$', 
    view=WelcomePageTemplateView.as_view(), 
    name='index' 
), 
url(
    regex=r'^signup$', 
    view=include('account.urls'), 
    # name='signup' 
), 
url(
    regex=r'^(?P<slug>[\w]+)/settings/?', 
    view=include('account.urls'), 
) 

счет urls.py

url(
    regex=r'^$', 
    view=AccountCreateView.as_view(), 
    name="create_account" 
), 
+1

Не связано, но зачем вы визуализируете форму вручную? Не можете ли вы просто использовать что-то вроде '{{form.as_table}}' '{{form.as_table}}'? –

+0

Я хочу больше контролировать представление форм. as_p на самом деле не дает мне этого. Кроме того, я лично никогда не использую таблицы для не табличных данных. – Staccato

ответ

2

Тег {% csrf_token %} нуждается в доступе к объекту запроса в шаблоне. Вы использовали render в своем AccountCreateView, который включает в себя запрос по умолчанию, но в вашем IndexPageTemplateView вы использовали свой render_to_response, а это не так.

Самый простой способ исправить индексный указатель - использовать render вместо render_to_response.

def get(self, request, *args, **kwargs): 
    # prevent logged in users from accessing welcome page 
    if self.request.user.is_authenticated(): 
     return HttpResponse(reverse("member_homepage", args=some_args)) 
    else: 
     return render(request, self.template_name) 

При переопределении представления на основе класса, обычно это плохая идея, чтобы переопределить get и post, потому что вы в конечном итоге дублирования (или нарушения) функциональности. В вашем случае было бы лучше позвонить super() вместо написания собственного кода, чтобы вернуть ответ.

def get(self, request, *args, **kwargs): 
    # prevent logged in users from accessing welcome page 
    if self.request.user.is_authenticated(): 
     return HttpResponse(reverse("member_homepage", args=some_args)) 
    else: 
     return super(IndexPageTemplateView, self).get(request, *args, **kwargs) 
+0

Спасибо. Просто любопытно, не является ли render_to_response просто слоем абстракции на вершине рендера? – Staccato

+1

«render» и «render_to_response» - это ярлыки. Разница заключается в том, что 'render' делает запрос доступным в контексте шаблона, но' render_to_response' не делает. Ярлык «render» был добавлен позже, чем 'render_to_response', но он доступен с момента выхода в Django 1.3. Ярлык ['render_to_response'] (https://docs.djangoproject.com/en/1.9/topics/http/shortcuts/#render-to-response) не рекомендуется и, скорее всего, будет устаревшим в будущем. Если вы всегда используете 'render', тогда вы не ошибетесь! – Alasdair

+0

Удивительный! Спасибо. У меня есть рефакторинг. – Staccato