反转模型与URL中的Slug不起作用

时间:2018-01-26 04:03:36

标签: django reverse generic-foreign-key

我有一个引用模型Part的parts.html页面,我遇到的页面是Part List Generic Model视图。它的目的是列出页面上的所有部分并显示它旁边的类别。每个部分都有一个外键“类别”。我正在尝试从Part列表视图创建Slug URL到Category详细信息页面,但是当我转到partlistview页面时收到此错误。我可以访问带有门户/类别/类别的类别页面,其中最后的第二个类别是数据库中的类别。

注意:下面的整个python文件都是按比例缩放的,我只粘贴在相关信息中,因为信息太多了。

django.urls.exceptions.NoReverseMatch: Reverse for 'category-detail' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['portal/category/(?P<slug>[-\\w]+)/$']

Views.py

class PartDetailView(LoginRequiredMixin, generic.DetailView):
    model = Part
    template_name = 'portal/part.html'  # Option - Specify your own template name/location

class PartListView(LoginRequiredMixin, generic.ListView):
    model = Part
    #queryset = Part.objects.filter(is_active=True) #.prefetch_related('user') #hos

    paginate_by = 100
    https://simpleisbetterthancomplex.com/tutorial/2017/03/13/how-to-create-infinite-scroll-with-django.html
    template_name = 'portal/parts.html'  # Option - Specify your own template name/location
    context_object_name = 'part_list'

    #def get_queryset(self):
        #return Category.objects.all()

    def get_context_data(self, **kwargs):
         context = super(PartListView, self).get_context_data(**kwargs)
         context['category'] = Category.objects.all()
         return context

class CategoryDetailView(LoginRequiredMixin, generic.DetailView):
    model = Category
    template_name = 'portal/category.html'  # Option - Specify your own template name/location
    slug_field = 'category'
    slug_url_kwarg = 'category'

Models.py

@python_2_unicode_compatible
class Category(BaseModel):
    """
    Model representing a part type (wiper, wheel, brake).
    """
    id = models.BigAutoField(primary_key=True)
    category = models.CharField(max_length=120, help_text=_("Category to organize parts into (wheel, wiperblade, brake)"))
    slug = models.SlugField(editable=False, unique=True, db_index=True)

    def __str__(self):  
        return '%s' % (self.category)

    def get_absolute_url(self):
        return reverse('portal:category-detail', kwargs={'slug': self.slug})  # str(self.trailer_number) kwargs={'slug': self.slug} instead of args=[self.slug]??

    def save(self, *args, **kwargs):
        self.slug = slugify(self.category)
        super(Category, self).save(*args, **kwargs)

    class Meta:
        db_table = 'category'
        verbose_name = _('category')
        verbose_name_plural = _('categories')
        ordering = ['category']

@python_2_unicode_compatible
class Part(BaseModel):

    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=120, help_text=_("The unique name or part number to identify this particular item"))
    category =  models.ForeignKey(Category, on_delete=models.PROTECT, help_text='Category to organize parts into (wheel, wiperblade, brake)', related_name='part', null=True, blank=True) 
    brand = models.CharField(max_length=80, blank=True, help_text=_("The name of the manufacturer that originaly built this part"), null=True)  
    minimum_inventory_quantity = models.PositiveSmallIntegerField(default=0, help_text=_("The minimum inventory quantity of this part before more need to be ordered"))

    def get_absolute_url(self):
        return reverse('portal:part-detail', args=[str(self.id)])


    def __str__(self):  
        return '%s - %s' % (self.name, self.brand)


    class Meta:
        unique_together = ("name", "brand",)  #NOTE: Each SKU + Carrier should also be unique together  #unique_together = (("name", "manufacturer"), ("sku", "Carrier"))
        ordering = ["name", "brand",]

Urls.py

from django.conf.urls import url

from .views import PartDetailView, CategoryDetailView, PartListView, PartInstanceDetailView, PartVariantDetailView

urlpatterns = [

url(r'^parts/$', PartListView.as_view(), name='parts'),
    url(r'^parts/(?P<pk>\d+)/$', PartDetailView.as_view(), name='part-detail'),
url(r'^category/(?P<slug>[-\w]+)/$', CategoryDetailView.as_view(), name='category-detail'),

]

parts.html

<div class="table-responsive">
    <table class="table table-hover table-bordered table-striped">
      <thead>
        <tr>
          <th>Category</th> 



          <th>Name</th> 
          <th>Brand</th>
          <th>Model Number</th>
          <th>Variants</th>
          <th>Stock</th>
          <th>Locations</th>
        </tr>
      </thead>
      <tbody>
        {% for part in part_list %}
          <tr>
            <td><strong><a href="{% url 'portal:category-detail' category.slug %}">{{ part.category.category }}</a></strong></td>
            <td><a href="{% url 'portal:part-detail' part.pk %}">{{ part.name }}</td>
            <td>{{ part.brand }}</td>
            <td>{{ part.part_variant.model_number }}</td>
            <td>{{ part.count_all }}</td>
            <td>{{ part.count_all }}</td>
            <td>{{ part.section.zone }}</td>
          </tr>
        {% empty %}
          {% if request.GET.q %}
            <tr>
              <td colspan="7" class="text-center bg-warning">No trailers found.</td>
            </tr>
          {% else %}
            <tr>
              <td colspan="7" class="text-center bg-warning">There are no trailers in the system.</td>
            </tr>
          {% endif %}
        {% endfor %}
      </tbody>
    </table>
  </div>

2 个答案:

答案 0 :(得分:0)

我不完全确定,但我认为您的 urls.py 在网址列表前需要app_name = portal

docs中阅读更多内容。

答案 1 :(得分:0)

您的网址格式需要关键字参数,但url模板标记将类别slug 作为未命名的参数传递。

这样做{% url "portal:category-detail" slug=category.slug %}, 因为在你的网址模式中你命名了你的捕获组&#34; slug&#34;。

另外,请确保category.slug实际上正在返回某些内容。