मेरे पास कई मॉडल के साथ दो मॉडल हैं:

class Topping(models.Model):
    name = models.CharField(max_length=200)

class Pizza(models.Model):
    name = models.CharField(max_length=200)
    toppings = models.ManyToManyField(Topping, blank=True)

पिज्जा अपडेट करने के लिए मेरे पास यह फॉर्म है:

class PizzaUpdateForm(forms.ModelForm):
    class Meta:
        model = Pizza
        fields=('name', 'toppings')
        widgets={'toppings': Select2TagWidget}

Select2TagWidget को django_select2 से इंपोर्ट किया गया है। मैं इसका उपयोग गतिशील पिज़्ज़ा टॉपिंग निर्माण की अनुमति देने के लिए करना चाहूँगा (अच्छा लगता है, है ना?)

इस दृश्य के माध्यम से इस प्रपत्र का उपयोग किया जाता है:

def update_pizza(request, pk):
    pizza = Pizza.objects.get(pk=pk)
    if request.method == 'POST':
        form = PizzaUpdateForm(request.POST, instance=pizza)
        if form.is_valid():
            form.save()
    else:
        form = PizzaUpdateForm(instance=pizza)
    return render(request, 'pizza/pizza_form.html',
                  {'form': form, 'pizza': pizza})

अभी, यह पूर्व-पंजीकृत टॉपिंग के लिए काम करता है लेकिन मैं अपने उपयोगकर्ताओं को इसी फॉर्म के माध्यम से नए टॉपिंग को परिभाषित करने की अनुमति देना चाहता हूं, यही कारण है कि मैं select2 पहले स्थान पर। दुर्भाग्य से, अगर मैं अभी ऐसा करता हूं, तो फॉर्म मान्य नहीं होता है, जिसकी अपेक्षा की जानी चाहिए।

अगर मैं अवैध_टॉपिंग जोड़ने का प्रयास करता हूं, तो यहां क्या होता है:

"illegal_topping" is not a valid value.

मुझे लगता है कि नए टॉपिंग बनाने के लिए get_or_create या कुछ इसी तरह का उपयोग करके फॉर्म.is_valid() को कॉल करने से पहले मुझे if request.method == 'POST' ब्लॉक में form['toppings'].value() से अधिक पुनरावृति करने की आवश्यकता है।

हालांकि, अगर मैं ऐसा करता हूं, तो मान मौजूदा टॉपिंग आईडी और नए टॉपिंग के नामों का मिश्रण हैं। सब कुछ एक स्ट्रिंग है, इसलिए मुझे यकीन नहीं है कि कैसे मूल्यांकन किया जाए कि कौन से नए टॉपिंग हैं और कौन से पहले से मौजूद थे।

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

हो सकता है कि मेरा दृष्टिकोण पूरी तरह से गलत है क्योंकि मैं वेब विकास और विशेष रूप से Django के लिए नया हूं, इसलिए मुझे इस पर आपका इनपुट प्राप्त करना अच्छा लगेगा। मुझे ऐसा लगता है कि यह एक अपेक्षाकृत सामान्य समस्या होनी चाहिए... लेकिन मुझे मदद नहीं मिली (या समझ में)। मुझे पता है कि कुछ M2M समस्याएं होनी चाहिए जिनका मैं अनुमान नहीं लगा रहा हूं, इसलिए कोई भी मार्गदर्शन स्वागत से अधिक है।

0
nicoco 15 जून 2018, 18:15

1 उत्तर

सबसे बढ़िया उत्तर

मुझे एक गंदा रास्ता मिल गया।

class PizzaUpdateForm(forms.ModelForm):
    class Meta:
        model = Pizza
        fields=('name', 'toppings')
        widgets={'toppings': Select2TagWidget}

    toppings = forms.ModelMultipleChoiceField(queryset=Topping.objects.all(),
                                              to_field_name='name',
                                              widget=Select2TagWidget,
                                              required=False)

def update_pizza(request, pk):
    pizza = Pizza.objects.get(pk=pk)
    if request.method == 'POST':
        form = PizzaUpdateForm(request.POST, instance=pizza)
        for topping_name in form['toppings'].value():
            topping, created = Topping.objects.get_or_create(name=topping_name)
            if created: topping.save()
        if form.is_valid():
            form.save()
    else:
        form = PizzaUpdateForm(instance=pizza)
    return render(request, 'pizza/pizza_form.html',
                  {'form': form, 'pizza': pizza})

हालांकि, मुझे लगता है कि यह बेहतर होगा यदि टॉपिंग निर्माण तर्क दृश्य में नहीं था लेकिन pizza.forms मॉड्यूल में था। मुझे लगता है कि यह अभी के लिए करेगा।

0
nicoco 16 जून 2018, 10:17