Django не возвращает данные из базы данных на той же HTML-странице, что и форма
Это мой финальный проект для моего класса в колледже, и они потребовали от нас сделать много ненужных шагов в разработке Я думаю, что, возможно, переусложнил свой код, но я не уверен, что лучший способ исправить это. Я могу получить данные из формы в базу данных, а затем передать эти данные в соответствующее представление, где оно запрашивает yelp и помещает их в JSON-файл, а затем определенные поля из JSON-файла сохраняются в базе данных. Моя проблема в том, что я не могу отобразить данные базы данных. После просмотра моего кода я думаю, что на этом пути может быть слишком много шагов. Я думаю, что есть более простой способ сделать это, но я не хочу разрушить то, что я пытаюсь понять и сделать это еще хуже. Я также обеспокоен тем, что я сделал такой беспорядок в вещах, что он нуждается в капитальном ремонте, но я, возможно, паникую lol. Я не против беспорядка, если я могу заставить информацию отображаться на HTML-странице, но я хотел бы знать, какой лучший способ написать это, если кто-то хочет этим заняться. Я пробовал множество вариантов HTML-страницы, чтобы получить данные, но это не работает, как бы я ни писал, поэтому я подумал, что, возможно, страница перезаписывается yelping, потому что я получаю сообщение об успехе поиска, когда я должен возвращать данные на страницу из query_api. Я добавил несколько операторов печати, чтобы посмотреть, что происходит, и обнаружил, что мой dict - это только одна часть данных, а не все поля строки, и я не уверен, почему это так. Я пробовал такие вещи, как
{% for key, values in yelp_data.items %}
<tr>
<td>{{key}}</td>
{% for v in values %}
<td>{{v}}</td>
{% endfor %}
</tr>
{% endfor %}
но я получаю ошибку "Business is not iterable".
Вот мой код:
index.html
...
<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
<p>
Click here to begin with Yelp!
</p>
<p><a class="btn btn-default" href="yelping">Yelp! »</a></p>
</div>
...
views.py
...
@csrf_exempt
def yelping(request):
if request.method == "POST":
form = YelpForm(request.POST or None)
if form.is_valid():
form.save(commit=False)
term = request.POST['term']
location = request.POST['location']
form.save()
print("yelping", term, location)
yelp_main(request)
messages.success(request, "Search successful." )
return render(request, 'app/yelp.html', {'form' : form})
else:
form = YelpForm()
messages.error(request, "Unsuccessful Search. Invalid information.")
form = YelpForm()
assert isinstance(request, HttpRequest)
return render(request, 'app/yelp.html')
...
yelp.py
yelp.html
{% extends "app/layout.html" %}
{% block content %}
<h2>{{ title }}</h2>
<form name='YelpForm' action="" class="post-form" method="post">
{% csrf_token %}
<label for="term">Term: </label>
<input id="term" type="text" name="term" placeholder="Type..." value="{{ YelpForm.term }}">
<label for="location">Location: </label>
<input id="location" type="text" name="location" placeholder="Where..." value="{{ YelpForm.location }}">
<input type="submit" value="OK">
</form>
<h1>{{ yelp_data.business_name }}</h1>
{% endblock %}
app/urls.py
from django.urls import re_path, path
from app import views
from .API.YelpAPI.yelp import yelp_main, query_api
# SET THE NAMESPACE!
app_name = 'app'
# Be careful setting the name to just /login use userlogin instead!
urlpatterns=[
path('yelp_main/', yelp_main, name='yelp_main' ),
path('query_api/', query_api, name='query_api'),
path('registration/', views.register_request, name='registration'),
re_path(r'^user_login/$', views.user_login,name='user_login'),
]
capstone/urls.py
from datetime import datetime
from django.urls import re_path, path, include
from django.contrib import admin
from django.contrib.auth.views import LoginView, LogoutView
from app import forms, views
urlpatterns = [
path('home/', views.home, name='home'),
path('contact/', views.contact, name='contact'),
path('about/', views.about, name='about'),
path('admin/', admin.site.urls),
re_path(r'^$',views.index,name='index'),
re_path(r'^special/',views.special,name='special'),
re_path('', include('app.urls', namespace='app')),
re_path(r'^logout/$', views.user_logout, name='logout'),
path('foodie/', views.foodie, name='foodie'),
path('yelping/', views.yelping, name='yelping'),
]
models.py
...
class Business(models.Model):
business_id = models.CharField(max_length=100)
business_name = models.CharField(max_length=100)
yelp_business_id = models.CharField(max_length=45, blank=True, null=True)
phone = models.CharField(max_length=100)
city = models.CharField(max_length=100)
state = models.CharField(max_length=100)
address = models.CharField(max_length=100, blank=True, null=True)
postal_code = models.CharField(max_length=15, blank=True, null=True)
latitude = models.DecimalField(max_digits=100, decimal_places=2, blank=True, null=True)
longitude = models.DecimalField(max_digits=100, decimal_places=2, blank=True, null=True)
business_stars = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=False)
business_review_count = models.IntegerField(blank=True, null=True)
is_open = models.IntegerField(blank=True, null=True)
class Meta:
managed = True
db_table = 'business'
ordering = ['business_name', 'business_stars', 'is_open']
verbose_name = 'Business Information'
verbose_name_plural = "Business's Information"
def __str__(self):
return self.business_name
...
class YelpInputModel(models.Model):
term = models.CharField(blank=True, null=False, max_length=100)
location = models.CharField(blank=True, null=False, max_length=100)
class Meta:
managed = True
db_table = 'yelpinputmodel'
...
python.exe
Performing system checks...
System check identified no issues (0 silenced).
November 11, 2022 - 10:20:42
Django version 4.1.3, using settings 'capstone.settings.development'
Starting development server at http://127.0.0.1:61098/
Quit the server with CTRL-BREAK.
[11/Nov/2022 10:20:43] "GET / HTTP/1.1" 200 2624
[11/Nov/2022 10:20:44] "GET /static/app/content/site.css HTTP/1.1" 200 723
[11/Nov/2022 10:20:44] "GET /static/app/content/bootstrap.min.css HTTP/1.1" 200 97968
[11/Nov/2022 10:20:44] "GET /static/app/scripts/modernizr-2.6.2.js HTTP/1.1" 200 52810
[11/Nov/2022 10:20:44] "GET /favicon.ico HTTP/1.1" 404 3796
[11/Nov/2022 10:20:50] "GET /yelping HTTP/1.1" 301 0
[11/Nov/2022 10:20:50] "GET /yelping/ HTTP/1.1" 200 2035
yelping dinner 08501
yelp_api dinner 08501
query_api dinner 08501
Querying https://api.yelp.com/v3/businesses/search ...
Querying https://api.yelp.com/v3/businesses/a0FEhgrOIk_M6_o0ie-NpQ ...
{'yelp_data': <Business: The Roost Restaurant>}
[11/Nov/2022 10:20:54] "POST /yelping/ HTTP/1.1" 200 2095
Проблема
Я признаю, что это выше моих сил, но я думаю, что суть в том, что ваша первая интуиция, что страница yelp.html
была перезаписана, была правильной. Ваша функция yelping
возвращает render(request, 'app/yelp.html')
, в которой нет данных, потому что ей не был задан контекст. Теперь эта функция представления сначала вызывает yelp_main(request)
, которая также возвращает render(request, 'app/yelp.html')
, страницу без данных. Но она вызывает def query_api(request, term, location):
. Этот возвращает данные со страницей, поскольку у него есть контекст, с ним, dic
. Но render(request, 'app/yelp.html', dic)
возвращается в query_api
, которая перезаписывает его версией страницы без данных, а затем первоначальная вызывающая функция заменяет его yelp_main
другой версией страницы без данных.
Возможное решение
Вместо того, чтобы возвращать страницы с рендером, не могли бы вы просто вернуть пустой HttpResponse, а затем только в конце отправить словарь:
# views.py
from django.http import HttpResponse
@csrf_exempt
def yelping(request):
form = YelpForm(request.POST or None)
if form.is_valid():
form.save(commit=False)
term = request.POST['term']
location = request.POST['location']
form.save()
print("yelping", term, location)
yelp_main(request)
messages.success(request, "Search successful." )
return redirect('app:yelping')
#return render(request, 'app/yelp.html', {'form' : form})
messages.error(request, "Unsuccessful Search. Invalid information.")
assert isinstance(request, HttpRequest)
yelp_data = Business.objects.filter(business_id=business_id).order_by('-id').first()
dic = {
'yelp_data': yelp_data,
}
print(dic)
return render(request, 'app/yelp.html', dic)
и
# yelp.py
from django.http import HttpResponse
@csrf_exempt
def yelp_main(request):
#request.session._get_or_create_session_key()
term = request.POST.get('term')
location = request.POST.get('location')
db()
print("yelp_api", term, location)
query_api(request, term, location)
return HttpResponse("OK")
#return render(request, 'app/yelp.html')
def query_api(request, term, location):
print("query_api", term, location)
response = search(API_KEY, term, location)
businesses = response.get('businesses')
if not businesses:
print(u'No businesses for {0} in {1} found.'.format(term, location))
return
business_id = businesses[0]['id']
response = get_business(API_KEY, business_id)
write_to_file = json.dumps([response], indent=4)
with open('app/API/YelpAPI/yelp.json', 'w') as f:
f.write(write_to_file)
return HttpResponse("OK")
#return render(request, 'app/yelp.html', dic)
Почему dict печатает только одну часть данных, а не все строки, я не знаю. Может быть, это Business.objects.filter(business_id=business_id).order_by('-id').first()
выдает такое?