Django: मैं एक पोस्ट को पुनर्निर्देशित कैसे करूं और पोस्ट डेटा पर पास करूं


80

जब Django views.py में POST अनुरोध संसाधित करते हैं, तो मुझे कभी-कभी इसे किसी अन्य url पर पुनर्निर्देशित करना होगा। यह url मैं उसी Django views.py फ़ाइल में किसी अन्य फ़ंक्शन द्वारा नियंत्रित किया जा रहा हूं। क्या ऐसा करने और मूल POST डेटा को बनाए रखने का एक तरीका है?

अद्यतन: मैं ऐसा क्यों करना चाहता हूं इसका अधिक विवरण। मेरे पास दो वेब ऐप हैं (चलो उन्हें ऐप्पा और ऐपबी कहते हैं) जो उपयोगकर्ता द्वारा पाठ क्षेत्र में दर्ज किए गए डेटा को स्वीकार करते हैं। जब उपयोगकर्ता सबमिट पर क्लिक करता है, तो डेटा संसाधित होता है और विस्तृत परिणाम प्रदर्शित होते हैं। AppA और AppB विभिन्न प्रकार के डेटा की अपेक्षा करते हैं। कभी-कभी एक उपयोगकर्ता गलती से AppB टाइप डेटा को AppA पोस्ट कर देता है। जब ऐसा होता है तो मैं उन्हें AppB पर पुनर्निर्देशित करना चाहता हूं और AppB परिणाम दिखाता हूं या कम से कम यह AppA में दर्ज किए गए डेटा के साथ पॉपुलेटेड होता है।

इसके अलावा:

  • क्लाइंट उन्हें केवल एक में संयोजित करने के बजाय दो अलग-अलग ऐप चाहता है।

  • मैं कोड नहीं दिखा सकता क्योंकि यह ग्राहक का है।

अद्यतन 2: मुझे लगता है कि KISS यहाँ सबसे अच्छा सिद्धांत है तय कर लिया है। मैंने दो ऐप्स को एक में जोड़ दिया है जो चीजों को सरल और अधिक मजबूत बनाता है; मुझे ग्राहक को यह समझाने में सक्षम होना चाहिए कि यह सबसे अच्छा तरीका है। सभी अच्छी प्रतिक्रियाओं के लिए धन्यवाद। अगर मैं वर्णित के रूप में दो एप्लिकेशन बनाए रखने जा रहा था, तो मुझे लगता है कि सत्र ऐसा करने का तरीका होगा - सुझाव देने के लिए मैथ्यू जे मॉरिसन के लिए धन्यवाद। Dzida के लिए धन्यवाद क्योंकि उनकी टिप्पणियों ने मुझे डिजाइन और सरलीकरण के बारे में सोचा।


क्या आपको वास्तव में क्लाइंट को रीडायरेक्ट भेजने की आवश्यकता है, या यह कुछ ऐसा है जो केवल एक फ़ंक्शन को कॉल करके और पोस्ट डेटा के सभी को पास करके किया जा सकता है?
मैथ्यू जे मॉरिसन

मुझे क्लाइंट के ब्राउज़र में url बदलने की आवश्यकता है, इसलिए यह एकमात्र तरीका है जिसे मैं करने की बात कर सकता हूं।
फनलोविनकोडर

और आप पहले पोस्ट डेटा के साथ सभी प्रसंस्करण नहीं कर सकते, और फिर इस तथ्य के बाद पुनर्निर्देशित कर सकते हैं?
मैथ्यू जे मॉरिसन

मेरे पास एक समान स्थिति है, लेकिन POST'ed डेटा या तो मौजूदा डेटा से मेल खाता है या नहीं है। यदि यह मेल खाता है, तो मुझे उस डेटा के लिए आईडी मिलती है, फिर उस आईडी को GET के माध्यम से स्क्रिप्ट पर रीडायरेक्ट में पास करें। मैं भी सेशन में POST डेटा सेव करता हूं। अब पुनर्निर्देशित पृष्ठ idGET द्वारा संदर्भित डेटा को लोड करता है , और POST द्वारा प्रस्तुत अन्य डेटा तक भी पहुंच रखता है।
बुटिक बटुकस २'१४

जवाबों:


57

यदि आपको इस तरह की समस्या का सामना करना पड़ा है, तो आपको अपने डिजाइनों को संशोधित करने की आवश्यकता हो सकती है।

यह HTTP का प्रतिबंध है कि POST डेटा रीडायरेक्ट के साथ नहीं जा सकता है।

क्या आप बता सकते हैं कि आप क्या हासिल करने की कोशिश कर रहे हैं और शायद तब हम कुछ साफ समाधान के बारे में सोच सकते हैं।

यदि आप सत्रों का उपयोग नहीं करना चाहते हैं, जैसा कि मैथ्यू ने सुझाव दिया है कि आप नए पेज में GET में POST params पास कर सकते हैं (क्वेरी स्ट्रिंग में सुरक्षा और GET params की अधिकतम लंबाई जैसी कुछ सीमाओं पर विचार करें)।

अपने अपडेट के लिए अपडेट करें :) यह मुझे अजीब लगता है कि आपके पास 2 वेब ऐप हैं और वे ऐप एक ही व्यूहोम का उपयोग करते हैं (क्या मैं सही हूं?)। वैसे भी GET में अपना डेटा POST से उचित दृश्य में पास करने पर विचार करें (यदि डेटा निश्चित रूप से संवेदनशील नहीं है)।


2
मैं देख सकता हूं कि वह जो करने की कोशिश कर रहा है वह वैध हो सकता है यदि वह एक समाप्त हो चुके लॉगिन को संभालने की कोशिश कर रहा है जो किसी उपयोगकर्ता को फ़ॉर्म सबमिट करने के बाद लॉगिन करने के लिए मजबूर करने वाला है ... उस स्थिति में, वह उसे बनाए रखना चाहता है। डेटा जो सबमिट किया गया था और लॉगिन स्क्रीन को पूरा करने के बाद उपयोगकर्ता को सब कुछ फिर से दर्ज करने के लिए मजबूर नहीं करता है।
मैथ्यू जे मॉरिसन

निश्चित नहीं है कि मुझे बिंदु मिला है, लेकिन इस मामले में पहले से ही थोड़ा कोड संशोधन और अनावश्यक रीडायरेक्ट किए बिना लॉगिन ऑपरेशन किया जा सकता है। अधिक सटीक सलाह देने के लिए एक्सिसिटिंग कोड पढ़ना बहुत अच्छा होगा।
दजिदा

मैं कह रहा हूं कि यदि आप एक फॉर्म सबमिट करते हैं, और आप लॉग इन नहीं होते हैं, तो आप एक लॉग इन फॉर्म पर पुनः निर्देशित होने जा रहे हैं ... उस परिदृश्य में, आप जो कुछ भी जमा करेंगे, उसे खो देंगे। मैं कुछ मौजूदा कोड को देखने में सक्षम होने के बारे में सहमत हूं।
मैथ्यू जे मॉरिसन

1
उपयोग मामला वैध है या नहीं, यह आप पर निर्भर करता है, मुझे उसी स्थिति का सामना करना पड़ता है जिसके लिए ताजा POST के साथ पुनर्निर्देशन सादगी और प्रतिरूपकता के मामले में सही समाधान है।
रबीह कोडेह

54

मुझे लगता है कि सत्र में पोस्ट डेटा को बचाने के लिए मैं शायद इस स्थिति को कैसे संभालूंगा, तब इसे हटा दें जब मुझे इसकी आवश्यकता नहीं होगी। इस तरह मैं उस पोस्ट के चले जाने के बावजूद मूल पोस्ट डेटा को रीडायरेक्ट कर सकता हूं।

क्या आप जो करने की कोशिश कर रहे हैं, उसके लिए वह काम करेगा?

यहाँ एक कोड नमूना है जो मैं सुझा रहा हूँ: (ध्यान रखें कि यह अनुपयोगी कोड है)

def some_view(request):
    #do some stuff
    request.session['_old_post'] = request.POST
    return HttpResponseRedirect('next_view')

def next_view(request):
    old_post = request.session.get('_old_post')
    #do some stuff using old_post

एक और बात ध्यान में रखें ... यदि आप ऐसा कर रहे हैं और फाइलें अपलोड भी कर रहे हैं, तो मैं इसे इस तरह से नहीं करूंगा।


1
मैंने कभी भी सत्र का उपयोग नहीं किया है, लेकिन मैं उस धन्यवाद पर एक नज़र डालूंगा।
फनलोविनकोडर

1
यह सबसे अच्छा अभ्यास नहीं है, लेकिन फिर भी मदद करता है। मुझे लगता है कि इस मुद्दे के लिए हमें कुछ भी नहीं मिलेगा।
गिलहर्मे डेविड दा कोस्टा

@GuilhermeDaviddaCosta आप यह क्यों कहते हैं कि यह सबसे अच्छा अभ्यास नहीं है? क्या आप हमें संकेत दे सकते हैं?
बुटिक बटुकस

क्योंकि सत्र में बहुत अधिक डेटा संग्रहीत करना एक बहुत अच्छा विचार नहीं है। लेकिन जैसा कि मैंने कहा, मैं कुछ भी सुंदर नहीं सोच सकता।
गुइलहर्मे डेविड दा कोस्टा

4
ठीक है, यह इस बात पर निर्भर करता है कि आप अपना सत्र कहां से जमा कर रहे हैं। हाल ही में Ive लोगों को हर अनुरोध के लिए सत्र और लोड बैलेंस (राउंड रॉबिन का उपयोग करके) के लिए एक पूरे सर्वर का उपयोग करते हुए देख रहा है। मैं आपको सलाह नहीं देना चाहता कि मैं कैंट के लिए खड़े हो जाऊं, लेकिन मैं फाइल को टेम्प के रूप में सहेजूंगा और सत्र के लिए इसके लिए केवल एक लिंक प्राप्त करूंगा। लगता है इन दिनों कोई भी राम से बाहर नहीं निकल रहा है।
गुइलहर्मे डेविड दा कोस्टा

23

आपको एक HTTP 1.1 अस्थायी पुनर्निर्देशित (307) का उपयोग करने की आवश्यकता है ।

दुर्भाग्य से, Django redirect()और HTTPResponseRedirect (स्थायी) केवल एक 301 या 302 लौटाते हैं। आपको इसे स्वयं लागू करना होगा:

from django.http import HttpResponse, iri_to_uri
class HttpResponseTemporaryRedirect(HttpResponse):
    status_code = 307

    def __init__(self, redirect_to):
        HttpResponse.__init__(self)
        self['Location'] = iri_to_uri(redirect_to)

Django.http मॉड्यूल भी देखें ।

संपादित करें:

हाल के Django संस्करणों पर, iri_to_uriआयात को इसमें बदलें :

from django.utils.encoding import iri_to_uri

Django के नए संस्करण स्थाई रिडायरेक्ट HttpResponsePermanentRedirect लेकिन यकीन नहीं है अगर यह मूल समस्या का हल है docs.djangoproject.com/en/dev/ref/request-response/...
JiminyCricket

9

उपयोग requestsपैकेज। लागू करने के लिए बहुत आसान है

pip install requests

तब आप किसी भी विधि से किसी भी यूआरएल को कॉल कर सकते हैं और डेटा ट्रांसफर कर सकते हैं

आपके विचार में आयात अनुरोध

import requests

डेटा पोस्ट करने के लिए, प्रारूप का पालन करें

r = requests.post('http://yourdomain/path/', data = {'key':'value'})

django दृश्य में पूर्ण url प्राप्त करने के लिए, उपयोग करें

request.build_absolute_uri(reverse('view_name'))

इस प्रकार django view कोड दिखता है

r = requests.post(
            request.build_absolute_uri(reverse('view_name')), 
            data = {'key':'value'}
    )

rप्रतिक्रिया वस्तु status_codeऔर contentविशेषता कहां है । r.status_codeस्थिति कोड देता है (सफलता पर यह 200 होगा) और r.contentप्रतिक्रिया का शरीर देता है। एक json विधि ( r.json()) है जो प्रतिक्रिया को json प्रारूप में बदल देगी

अनुरोध

अनुरोध


4

उसी अनुरोध ऑब्जेक्ट का उपयोग करके अपने नए दृश्य को अपने पुराने दृश्य से कॉल करें। बेशक यह इस तरह के रूप में अनुप्रेषित नहीं होगा, लेकिन अगर आप सभी के बारे में परवाह करते हैं तो एक दृश्य से दूसरे में डेटा स्थानांतरित कर रहा है, तो यह काम करना चाहिए।
मैंने निम्नलिखित स्निपेट का परीक्षण किया और यह काम करता है।

from django.views.generic import View

class MyOldView(View):
    def post(self, request):
        return MyNewView().post(request)

class MyNewView(View):
    def post(self, request):
        my_data = request.body
        print "look Ma; my data made it over here:", my_data

1

आप इसके साथ रेंडर और संदर्भ का उपयोग कर सकते हैं :

Render(request,"your template path",        {'vad name' : var value}

आप टेम्प्लेट में vars को पुनः प्राप्त कर सकते हैं:

{% If var name %}
 {{ var name }}
{% endif %}

1

मुझे हाल ही में इसी तरह के मुद्दे का सामना करना पड़ा।

मूल रूप से मेरे पास एक फॉर्म ए था, इसे सबमिट करने पर एक और फॉर्म बी दिखाई देगा, जिसमें कुछ परिणाम + एक फॉर्म होता है। B सबमिट करने पर, मैं उपयोगकर्ता को कुछ अलर्ट प्रदर्शित करना चाहता था और केवल B पर उपयोगकर्ता को रखना चाहता था।

जिस तरह से मैंने इसे हल किया, वह <output>बी में, एक क्षेत्र में परिणाम प्रदर्शित करके है।

<output name="xyz" value="xyz">{{xyz}}</output>

और मैंने A-> B और B-> B के लिए समान दृश्य का उपयोग किया। अब मुझे केवल यह पता लगाना था कि अनुरोध ए या बी से आ रहा है या नहीं और उसी के अनुसार रेंडर किया जाए।

def view1(request):
    if "xyz" in request.POST:
        # request from B
        # do some processing
        return render(request, 'page.html', {"xyz":request.POST["xyz"]})
    else:
        # request from A
        res = foo() # some random function
        return render(request, 'page.html', {"xyz":res})

लेकिन यह केवल तभी काम करता है यदि फॉर्म बी छोटा है और यह गतिशील नहीं है।


0

यदि आप POST को संसाधित करने के बाद एक रीडायरेक्ट का उपयोग कर रहे हैं AppB, तो आप वास्तव में AppBविधि से विधि को कॉल करने से दूर हो सकते हैं AppA

एक उदाहरण:

def is_appa_request(request):
    ## do some magic.
    return False or True
is_appb_request = is_appa_request

def AppA(request):
    if is_appb_request(request):
       return AppB(request)
    ## Process AppA.
    return HttpResponseRedirect('/appa/thank_you/')

def AppB(request):
    if is_appa_request(request):
       return AppA(request)
    ## Process AppB.
    return HttpResponseRedirect('/appb/thank_you/')

यह अंत-उपयोगकर्ता के लिए एक पारदर्शी अनुभव प्राप्त करना चाहिए, और जो ग्राहक आपने काम पर रखा है, वह संभवतः अंतर को कभी नहीं जान पाएगा।

यदि आप POST के बाद पुनर्निर्देशित नहीं कर रहे हैं, तो क्या आप पृष्ठ को ताज़ा करने वाले उपयोगकर्ता के कारण डुप्लिकेट डेटा के बारे में चिंतित नहीं हैं?


यह बहुत अच्छा होगा अगर इस तरह से एक सरल समाधान काम किया। हालाँकि, मुझे डेटा संसाधित करने के बाद विस्तृत परिणाम प्रदर्शित करने की आवश्यकता है। इसके लिए सत्र की आवश्यकता होगी (जैसा कि मैथ्यू जे मॉरिसन ने प्रस्तावित किया है) क्या यह नहीं होगा?
फनलोविनकोडर

1
आप इसे तीन तरीकों में से एक कर सकते हैं। # 1, डेटाबेस में डेटा स्टोर करें और pkजब आप रीडायरेक्ट करें तो नई प्रविष्टि को पास करें । # 2, cacheबैकएंड में डेटा स्टोर करें , और कुंजी को फिर से पास करें। # 3, इसे सत्र में संग्रहीत करें। इनमें से कोई भी वेब-ऐप के लिए बिल्कुल सामान्य है, भले ही यह अस्थायी हो। यदि फॉर्म डेटा पार्स करने के लिए गैर-तुच्छ है, तो यह सिस्टम को तेज कर देगा यदि आउटपुट पहले से ही कैश था।
जैक एम।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.