#python #django
#python #django
Вопрос:
Я знаю, что моя проблема может заключаться в недостатке знаний Django, но я пытаюсь передать пользовательский ввод из одной формы в представлении в другое представление, которое затем отобразит HTML-страницу этого представления с заданным вводом.
Я перенаправлен нормально, но данные не отображаются. Я полагаю, что это как-то связано с тем, что контексты не передаются должным образом, но я не понимаю, что не так или как это исправить.
views.py
def home_view(request, *args, **kwargs):
print(args, kwargs)
print(request.user)
if request.method == 'POST':
form2 = PostForm(request.POST)
if form2.is_valid():
post = form2.save(commit=False)
post.poster = request.user
post.content = form2.cleaned_data.get('content')
post.title = form2.cleaned_data.get('title')
post.syntax = form2.cleaned_data.get('syntax')
post.public = form2.cleaned_data.get('public')
rand = str(uuid.uuid4())[:6]
while Paste.objects.filter(generated_url=rand):
rand = str(uuid.uuid4())[:6]
post.generated_url = rand
form2.save()
context = {
"poster_name": post.poster,
"paste_contents": post.content,
"paste_title": post.title,
"paste_syntax": post.syntax,
"paste_visible": post.public
}
return HttpResponseRedirect(reverse('details', args=(post.generated_url,)), context)
else:
form2 = PostForm()
return render(request, "home.html", {'form2': form2})
def detail_view(request, *args, **kwargs):
if request.user.is_authenticated:
if request.method=='POST':
form3 = PostForm(request.POST)
url = form3.generated_url
your_posts = Paste.objects.get(url)
context = {
'form3': form3
}
return render(request, "paste_detail.html", context)
return render(request, "paste_detail.html", {'form3': form3})
home.html
{% extends "base.html" %}
{% block content %}
<h1>Your user is {{ request.user }}</h1>
<div class="submit_form">
<form action="" method="POST">
{% csrf_token %}
{{ form2.as_p }}<br>
<input type="submit" name="submit" value="Paste" id="submit">
</div>
{% endblock content %}
И paste_detail.html
{% extends "base.html" %}
{% block content %}
<!--<h1>Name of post: {{ post.title }}</h1>-->
<p>Content of post:</p>
I AM REDIRECTED
<h1>Name of post: {{ form2.title }}</h1>
<p>Content of post:</p>
<p>{{form3.content|linebreaks}}</p>
{{ form3.poster }}
{{ form3.contents }}
{{ form3.title }}
{{ form3.syntax }}
{{ form3.visible }}
{% endblock %}
Редактировать:
views.py
def home_view(request, *args, **kwargs):
if request.method == 'POST':
form2 = PostForm(request.POST)
if form2.is_valid():
post = form2.save(commit=False)
post.poster = request.user
post.save()
rand = str(uuid.uuid4())[:6]
while Paste.objects.filter(generated_url=rand):
rand = str(uuid.uuid4())[:6]
post.generated_url = rand
# return HttpResponseRedirect(reverse('details', args=(post.generated_url,)), context)
return redirect('detail', rand)
else:
form2 = PostForm()
return render(request, "home.html", {'form2': form2})
def detail_view(request, custom_uuid):
post = get_object_or_404(Paste, pk=pk)
return render(request, "paste_detail.html", {'post': post})
#return render(request, "paste_detail.html", {'form3': form3})
paste_detail.html
{% extends "base.html" %}
{% block content %}
<p>Content of post:</p>
I AM REDIRECTED
<h1>Name of post: {{ post.title }}</h1>
<p>Creator of post:</p> {{ post.poster }}
<p>Content of post:</p> {{ post.content }}
<p>Title of post:</p> {{ post.title }}
{{ post.syntax }}
{{ post.visible }}
{% endblock %}
И urls.py
...
urlpatterns = [
path('home/', home_view, name='home'),
path('contact/', contact_view, name='contact'),
path('admin/', admin.site.urls, name='admin'),
path('about/', about_view, name='about'),
url(r'^signup/$', views.signup, name='signup'),
path('paste_list/', paste_list_view, name='paste_list'),
url(r'^$', home_view),
#url(r'^(?P<rand_url>S{6})/$', detail_view, name='details'),
path('detail/<str:custom_uuid>/', detail_view, name='detail'),
path('accounts/', include('django.contrib.auth.urls')),
]
Комментарии:
1. Шаблон называется
page_detail.html
илиpaste_detail.html
?2. @JohnGordon
paste_detail.html
Извините за опечатку, я это исправлю
Ответ №1:
В вашем коде есть несколько проблем. Давайте исправим их один за другим (пожалуйста, проверьте комментарии к коду для объяснения):
В home_view
вы выполняете некоторые избыточные коды, вы можете упростить их следующим образом:
from django.shortcuts import redirect
...
if request.method == 'POST':
form2 = PostForm(request.POST)
if form2.is_valid():
post = form2.save(commit=False) # it is not saved in db
post.poster = request.user
rand = str(uuid.uuid4())[:6]
while Paste.objects.filter(generated_url=rand).exists():
rand = str(uuid.uuid4())[:6]
post.generated_url = rand
post.save() # it will save all information to DB, so you don't need to call form2.cleaned_data.get(..)
return redirect('details', custom_uuid=rand) # I am redirecting to `detail_view`. here `rand` is the random uuid of the post which is saved in db
else:
form2 = PostForm()
return render(request, "home.html", {'form2': form2}) # rendering form for GET request
Теперь давайте обновим подробный вид, чтобы перехватить перенаправление:
from django.shortcuts import get_object_or_404
def detail_view(request, custom_uuid):
post = get_object_or_404(Post, generated_url=custom_uuid) # getting the post object from database using model.
return render(request, "post_detail.html", {'post': post}) # sending data in context to template
# url
path('detail/<str:custom_uuid>/', detail_view, name='detail') # here <str:custom_uuid> will catch the uuid sent in the url
# HTML
{% extends "base.html" %}
{% block content %}
<p>Content of post:</p>
I AM REDIRECTED
<h1>Name of post: {{ post.title }}</h1> // <-- getting this context from view
<p>Content of post:</p>
<p>{{post.content|linebreaks}}</p>
{{ post.poster }}
{{ post.contents }}
{{ post.title }}
{{ post.syntax }}
{{ post.visible }}
{% endblock %}
Здесь get_object_or_404 получает запись для модели Post
, если она не найдена, то выдает ошибку 404.
Комментарии:
1. Это действительно имеет смысл. Однако, если бы я не хотел использовать структуру URL, такую как
webapp.com/detail/pkid
, а скорее хотел использоватьwebapp.com/generated_url
, как бы я изменил код, чтобы отразить это? В моемviews.py
вы можете видеть, что я создаю случайную строку, выполняя `rand = str(uuid.uuid4())[:6] при вставке.objects.filter(generated_url=rand): rand = str(uuid.uuid4())[:6] post.generated_url = rand`2. Вы можете передать UUID, сгенерированный в
generated_url
. Вы можете использоватьpath('detail/<str:custom_uuid>/'...)
и перехватить этот uuid в представлении с помощьюdef detail(request, custom_uuid):..
3. Возможно, я неправильно вас понимаю. Я изменяю значение return на
return redirect('detail', rand)
в представлении home, меняя detail_view def наdef detail_view(request, custom_uuid)
и url.py чтобы иметьpath('detail/<str:custom_uuid>/', detail_view, name='detail'),
? Я отредактирую свой OP для удобства чтения, пожалуйста, взгляните. Спасибо.4. @NickM Я обновил свой ответ. пожалуйста, взгляните.
5. по какой-то причине я получаю
No Paste matches the given query.
ошибку при попытке отправки с домашней страницы.
Ответ №2:
Контексты предоставляются для каждого запроса. Как только ваше представление вернется, контекст больше не существует. Когда вы выполняете перенаправление, вы завершаете этот цикл запроса / ответа и запускаете другой с вашим detail
представлением. Ни один из контекстов не будет перенесен.
Вместо этого вам нужен способ сохранять соответствующую информацию между запросами. Один довольно простой способ сделать это — сохранить данные в сеансе.
Например, вы могли бы сохранить title
в сеансе, подобном этому, в home_view
:
request.session['title'] = post.title
И затем, на ваш detail_view
взгляд, вы могли бы добавить его в свой контекст:
context = {
'title': request.session.get('title')
}
Ознакомьтесь с документацией Django о сеансах для получения дополнительной информации: https://docs.djangoproject.com/en/2.1/topics/http/sessions /
Комментарии:
1. Использование сеансов имеет смысл. Я синтаксически запутался в том, как действовать дальше. Не могли бы вы привести пример одного из полей, чтобы я мог лучше понять?
2. Нет проблем. Смотрите мой обновленный ответ. Возможно, вам все еще потребуется ознакомиться с документами, чтобы убедиться, что у вас правильно настроено хранилище сеансов (хотя я думаю , что это делается по умолчанию, если у вас все еще есть настройки Django по умолчанию.
3. Я рассмотрю это. Большое спасибо!