首页 > 解决方案 > Django: NoReverseMatch 在 /shop/stickers/minion-cushion/medida-y-cantidad

问题描述

我在尝试访问 2 Steps 表单的第二部分时遇到问题。

单击给定类别中的产品时,例如类别“贴纸”和产品“小黄人-靠垫”,用户将被带到以下网址:

/shop/stickers/minion-cushion/medida-y-cantidad

在这里,他们会找到一个表单“StepOneForm”,该表单仅将 tamanios(英文尺寸)和 cantidades(英文数量)显示为 forms.ChoiceFields。

我将捕获用户对此字段的选择并将值保存在session. 然后用户应该点击Continuar按钮并被带到这个网址:

/shop/stickers/minion-cushion/subir-arte

用户将在其中看到第二个表单“StepTwoForm”和将表单提交到数据库的按钮。

但是,在我的 StepOneForm 模板中使用它时,我收到此错误:

<a  href="{% url 'shop:UploadArt' %}" class="btn btn-naranja text-white btn-block">Continuar</a>

错误

NoReverseMatch at /shop/stickers/minion-cushion/medida-y-cantidad
Reverse for 'UploadArt' with no arguments not found. 1 pattern(s) tried: ['shop\\/(?P<c_slug>[-a-zA-Z0-9_]+)\\/(?P<product_slug>[-a-zA-Z0-9_]+)\\/subir\\-arte$']

但是将 a 标签 href 属性留空可以让我毫无问题地访问此页面(显然,单击 Continue 时我无法访问下一页)。

<a  href="" class="btn btn-naranja text-white btn-block">Continuar</a>

喜欢这个:

在此处输入图像描述

模板中的表格

<form method="post">
    {% csrf_token %}


    <div id="tamanios">

    <legend class="text-size20 bold-font"> {{ form.tamanios.label }}</legend>


    <ul class="form-items">
       <li>
            <span>
                {{ form.tamanios.0.tag }}
                {{ form.tamanios.0.choice_label }}
            </span>
       </li>                              
     </ul>

    </div>


    <a  href="{% url 'shop:UploadArt' %}" class="btn btn-naranja text-white btn-block"> Continuar </a>
    </br>
    <p>Siguiente: subir imagen</p>

</form>

我的网址

app_name = 'shop'

urlpatterns = [

    path('', views.allProdCat, name = 'allProdCat'),
    path('<slug:c_slug>', views.allProdCat, name = 'products_by_category'),
    path('<slug:c_slug>/<slug:product_slug>/medida-y-cantidad', views.StepOneView.as_view(), name='ProdCatDetail'),
    path('<slug:c_slug>/<slug:product_slug>/subir-arte', views.StepTwoView.as_view(), name='UploadArt'),

]

商店/views.py

class StepOneView(FormView):
    form_class = StepOneForm
    template_name = 'shop/product.html'
    success_url = 'shop/subir-arte'

    def get_initials(self):
         # pre-populate form if someone goes back and forth between forms
         initial = super(StepOneView, self).get_initial()
         initial['tamanios'] = self.request.session.get('tamanios', None)
         initial['cantidades'] = self.request.session.get('cantidades', None)
         return initial

         # pre-populate form if someone goes back and forth between forms

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['product'] = Product.objects.get(
            category__slug=self.kwargs['c_slug'],
            slug=self.kwargs['product_slug']
        )
        return context


    def form_valid(self, form):
        # In form_valid method we can access the form data in dict format
        # and will store it in django session
        self.request.session['tamanios'] = form.cleaned_data.get('tamanios')
        self.request.session['cantidades'] = form.cleaned_data.get('cantidades')
        return HttpResponseRedirect(self.get_success_url())


# here we are going to use CreateView to save the Third step ModelForm
class StepTwoView(CreateView):
    form_class = StepTwoForm
    template_name = 'shop/subir-arte.html'
    success_url = '/'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['product'] = Product.objects.get(
            category__slug=self.kwargs['c_slug'],
            slug=self.kwargs['product_slug']
        )
        return context

    def form_valid(self, form):
        form.instance.tamanios = self.request.session.get('tamanios')  # get tamanios from session
        form.instance.cantidades = self.request.session.get('cantidades')  # get cantidades from session
        del self.request.session['cantidades']  # delete cantidades value from session
        del self.request.session['tamanios']  # delete tamanios value from session
        self.request.session.modified = True
        return super(StepTwoView, self).form_valid(form)

商店/models.py

class Category(models.Model):
    name = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(max_length=250, unique=True)
    description = models.TextField(blank=True)
    image = models.ImageField(upload_to='category', blank=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'category'
        verbose_name_plural = 'categories'

    def get_url(self):
        return reverse('shop:products_by_category', args=[self.slug])

    def __str__(self):
        return '{}'.format(self.name)


class Product(models.Model):
    name = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(max_length=250, unique=True)
    description = models.TextField(blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    image = models.ImageField(upload_to='product', blank=True)
    stock = models.IntegerField()
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'product'
        verbose_name_plural = 'products'

    def get_url(self):
        return reverse('shop:ProdCatDetail', args=[self.category.slug, self.slug])

    def __str__(self):
        return '{}'.format(self.name)


class TamaniosCantidades(models.Model):

    # usuario = models.ForeignKey(User, on_delete=models.DO_NOTHING)
    producto = models.ForeignKey(Product, on_delete=models.CASCADE)
    tamanios = models.CharField(max_length=10, choices=TAMANIOS)
    cantidades = models.CharField(max_length=10, choices=CANTIDADES)
    imagenes = models.FileField(upload_to='imagenes/', null=True, blank=True)
    # imagenes = models.ImageField(upload_to='category', blank=True)
    instrucciones = models.CharField(max_length=200, blank=True, null=True, default='')
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.tamanios

商店/forms.py

class StepOneForm(forms.Form):
    tamanios = forms.ChoiceField(choices=TAMANIOS, widget=forms.RadioSelect(), label='Selecciona un tamaño')
    cantidades = forms.ChoiceField(choices=CANTIDADES, widget=forms.RadioSelect(), label='Selecciona la cantidad')


class StepTwoForm(forms.ModelForm):
    instrucciones = forms.CharField(widget=forms.Textarea)

    class Meta:
        model = TamaniosCantidades
        fields = ('imagenes', 'instrucciones')

    def __init__(self, *args, **kwargs):
        super(StepTwoForm, self).__init__(*args, **kwargs)
        self.fields['instrucciones'].required = False

标签: django

解决方案


因为uploadart有参数(c_slugproduct_slug):

path('<slug:c_slug>/<slug:product_slug>/subir-arte', 
     views.StepTwoView.as_view(), 
     name='UploadArt'),

您的网址必须告知此参数:

<a  href="{% url 'shop:UploadArt' _some_data_here_ _some_data_here_  %}"

看看django url docs samples


推荐阅读