Контекст не печатает Django

#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. Я рассмотрю это. Большое спасибо!