Вызов API на моем сервере из другого представления - PullRequest
9 голосов
/ 29 июня 2011

Итак, здесь какая-то странная ситуация. У меня есть проект Django, использующий TastyPie для питания его API и некоторые представления / шаблоны, которые будут использоваться для питания плагинов для различных сайтов. Вместо того, чтобы создавать эти плагины как стандартные шаблоны Django, меня попросили использовать наш API для обработки запросов к плагинам, что означает, что я вызываю представление на моем сервере из другого представления, и по какой-то причине это не работает с любым из моих взглядов. Для справки:

#views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template.context import Context, RequestContext
import json, urllib, urllib2

SITE_NAME = "http://localhost:8000/"
API_PATH = "api/v1/"

def aggregate(request):
    template = 'lemonwise/plugins/aggregate.html'
    sku = request.GET.get('sku')
    url = ''.join([SITE_NAME, API_PATH, 'product/?sku=', sku])
    product = json.loads(urllib.urlopen(url).read())['objects'][0]
    return render_to_response(template, product)

def reviews(request):
    template = 'lemonwise/plugins/reviews.html'
    sku = request.GET.get('sku')
    url = ''.join([SITE_NAME, API_PATH, 'product/?format=json&sku=', sku])
    #Comment the next line out and the url is passed correctly
    response = urllib2.build_opener().open(url).read()
    return HttpResponse(url)
    #page = opener.open(url).read()
    #return HttpResponse(url)
    #product = json.loads(urllib2.build_opener().open(url).read())['objects'][0]
    #return HttpResponse(url)
    #reviews = [json.loads(urllib.urlopen(SITE_NAME + uri)) for uri in product['reviews']]
    #return render_to_response(template, {'reviews': reviews})

def survey(request):
    template = 'lemonwise/plugins/survey.html'
    sku = request.GET.get('sku')
    url = ''.join([SITE_NAME, API_PATH, 'product/?sku=', sku])
    product = json.loads(urllib2.build_opener().open(url).read())['objects'][0]
    return render_to_response(template, product)

def mosthelpfulpositive(request):
    template = 'lemonwise/plugins/mosthelpfulpositive.html'
    sku = request.GET.get('sku')
    url = ''.join([SITE_NAME, API_PATH, 'product/?sku=', sku])
    product = json.loads(urllib2.build_opener().open(url).read())['objects'][0]
    uri = product['most_helpful_positive']
    most_helpful_positive = json.loads(urllib.urlopen(SITE_NAME + uri))
    return render_to_response(template, most_helpful_positive)

def mosthelpfulnegative(request):
    template = 'lemonwise/plugins/mosthelpfulnegative.html'
    sku = request.GET.get('sku')
    url = ''.join([SITE_NAME, API_PATH, 'product/?sku=', sku])
    product = json.loads(urllib2.build_opener().open(url).read())['objects'][0]
    uri = product['most_helpful_negative']
    most_helpful_negative = json.loads(urllib.urlopen(SITE_NAME + uri))
    return render_to_response(template, most_helpful_negative)

И соответствующий urls.py (в другом приложении):

#urls.py    
from django.conf import settings
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

from tastypie.api import Api
from lemonwise.reviews.api import *

admin.autodiscover()

v1_api = Api(api_name='v1')
v1_api.register(UserResource())
v1_api.register(MerchantResource())
v1_api.register(ProductFamilyResource())
v1_api.register(ProductResource())
v1_api.register(BooleanAttributeResource())
v1_api.register(SlideAttributeResource())
v1_api.register(ProductAttributeResource())
v1_api.register(SubmissionResource())
v1_api.register(ReviewResource())
v1_api.register(ReviewProductAttributeResource())
v1_api.register(CommentResource())
v1_api.register(BestUseResource())
v1_api.register(HelpfulVoteResource())

#Acess the api via http://127.0.0.1:8000/api/v1/user/?format=json

urlpatterns = patterns('',
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin/', include(admin.site.urls)),

    # Lemonwise apps
    url(r'^reviews/', include('lemonwise.reviews.urls')),

        #API
        url(r'^api/', include(v1_api.urls)),
)

if settings.DEBUG:
    urlpatterns += staticfiles_urlpatterns()

Есть идеи, как это исправить? Я не могу найти никаких записей по этому вопросу.

РЕДАКТИРОВАТЬ: Более конкретно, происходит то, что, когда я загружаю любое из этих представлений, они зависают, пытаясь прочитать страницу API. Кроме того, мой сервер не показывает никаких признаков обработки каких-либо запросов. (Хотя я могу загрузить страницы API напрямую.)

Ответы [ 4 ]

6 голосов
/ 30 июня 2011

Теперь ваш комментарий прояснил ситуацию, я могу предположить, в чем проблема.Дело в том, что вы используете встроенный сервер разработки, который является однопоточным.Поэтому, пока он обрабатывает исходный запрос, он не может обработать внутренний запрос для другого URL-адреса - так что он зависает на неопределенное время.

Решение, как указывает Мао, состоит в том, чтобы подумать о лучшей архитектуре.Если вы не можете этого сделать, вам может повезти с использованием чего-то вроде gunicorn вместо встроенного сервера.

2 голосов
/ 09 февраля 2012

Согласен, ваш сервер разработки, вероятно, имеет только один экземпляр. Запустите еще один на другом порту. т.е. / SITE_NAME = "http://localhost:8001/"

2 голосов
/ 30 июня 2011

В частности, для Tastypie вы можете использовать свои ресурсы в представлениях, если вам это необходимо, для непосредственного доступа к объектам и вызова методов get и построения пакета.

Вы можете узнать, как: http://django -tastypie.readthedocs.org / ru / latest / cookbook.html

Перейти к разделу, озаглавленному - Использование вашего ресурса в обычных представлениях

0 голосов
/ 29 июня 2011

Хорошо, я уже сказал, что иметь представления, создающие HTTPRequest для других представлений, довольно глупо, но я вижу, в чем ваша проблема в настоящее время.Вы звоните json.loads(urllib.urlopen(SITE_NAME + uri)), но urllib.urlopen возвращает файлоподобный объект, а не строку, поэтому на самом деле это должно быть json.load(urllib.urlopen(SITE_NAME + uri)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...