2

Хорошо, я довольно новичок в этом, я работаю над своим проектом уже пару месяцев, и мне бы хотелось создать URL-адреса, которые принимают несколько параметров для вызова вида. Образец URL будет выглядеть следующим образом: http://www.sample.com/builders//м //Использование нескольких URL-параметров для get_object в классе-вид

У меня это успешно реализуется, путем переопределения get_object в моем DetailView, но мне интересно, если есть лучше/проще способ для выполнения этого или если это считается плохой практикой. Любые рекомендации будут оценены.

urls.py

urlpatterns = [ 
    # url(r'^$', builder_list, name='list'), 
    # url(r'^create/$', builder_create, name='create'), 
    # url(r'^(?P<slug>[\w-]+)/$', builder_detail, name='detail'), 
    # url(r'^(?P<slug>[\w-]+)/edit/$', builder_update, name='update'), 
    # url(r'^(?P<slug>[\w-]+)/delete/$', builder_delete, name='delete'), 

    # url(r'^$', builder_list, name='sub_list'), 
    # url(r'^m/create/$', sub_create, name='sub_create'), 
    url(r'^(?P<builder>[\w-]+)/m/(?P<market>[\w-]+)/$', sub_detail, name='sub_detail'), 
    # url(r'^m/(?P<slug>[\w-]+)/edit/$', sub_update, name='sub_update'), 
    # url(r'^m/(?P<slug>[\w-]+)/delete/$', sub_delete, name='sub_delete'), 
] 

views.py

class BuilderSubDetailView(DetailView): 
    model = BuilderSub 
    template_name = "builders/sub_detail.html" 

    def get_context_data(self, **kwargs): 
     context = super(BuilderSubDetailView, self).get_context_data(**kwargs) 
     context['now'] = timezone.now() 
     print(context) 

     return context 

    def get_object(self, queryset=None): 
     if queryset is None: 
      queryset = self.get_queryset() 

     # Next, try looking up by primary key. 
     builder = self.kwargs['builder'] 
     builder_id = Builder.objects.filter(slug=builder).first().pk 
     market = self.kwargs['market'] 
     market_id = Market.objects.filter(slug=market).first().pk 
     if builder is not None and market is not None: 
      queryset = BuilderSub.objects.filter(parent=builder_id).filter(market=market_id) 

     # If none of those are defined, it's an error. 
     if builder is None or market is None: 
      raise AttributeError("Generic detail view %s must be called with " 
           "Builder and Market" 
           % self.__class__.__name__) 
     try: 
      # Get the single item from the filtered queryset 
      obj = queryset.get() 
     except queryset.model.DoesNotExist: 
      raise Http404("No %(verbose_name)s found matching the query") % \ 
       {'verbose_name': queryset.model._meta.verbose_name} 
     return obj 

И models.py для справки - тоже есть какие-либо проблемы с моей функции get_absolute_url?

class Builder(models.Model): 
    added_by = models.ForeignKey(settings.AUTH_USER_MODEL, default=1) 
    company_name = models.CharField(max_length=80, help_text="Full Company Name", unique=True) 
    short_name = models.CharField(help_text="Short Company Name", max_length=30) 
    slug = models.SlugField(unique=True) 
    website = models.CharField(max_length=80, help_text="Format: www.[website].com") 
    logo = models.ImageField(blank=True, null=True) 
    timestamp = models.DateTimeField(auto_now_add=True) 
    info = RedactorField(verbose_name=u'Company Info') 

    def show_website_url(self): 
     return format_html("<a href='{url}'>{url}</a>", url=self.website) 

    def __str__(self): 
     return self.short_name 


class BuilderSub(models.Model): 
    parent = models.ForeignKey(Builder) 
    market = models.ForeignKey(Market, null=True, blank=True) 
    details = RedactorField(verbose_name=u'Details', blank=True, null=True) 
    main_contact = models.ForeignKey(Person, blank=True, null=True) 

    def __str__(self): 
     return "{}: {} - {}".format(self.pk, self.market.name, self.parent.short_name) 

    def get_absolute_url(self): 
     return reverse('builders:sub_detail', kwargs={'market': self.market.slug, 'builder': self.parent.slug}) 


def pre_save_builder_reciever(sender, instance, *args, **kwargs): 
    instance.slug = slugify(instance.short_name) 

pre_save.connect(pre_save_builder_reciever, sender=Builder) 

Я не 100% уверен, что я моя BuilderSub модель является подходящим способом урегулировать отношения между общими Builder (компании) и рынками они служат таким образом любое руководству было бы оценить как хорошо.

+0

Я уверен, что вы можете создавать несколько URL-адресов с разными параметрами, а затем указывать их все на один и тот же вид. –

ответ

0

Да, действительно, существует более этичный способ сделать это. DetailView предназначен для работы только с одним объектом. Однако ListView выполняет свою работу!

Я заменил строитель и рынок города и категории.

Я также являюсь новичком. Надеюсь, я ответил на ваш вопрос :)

views.py

class EntryListView(generic.ListView): 

template_name = 'myapp/category.html' 
context_object_name = 'entry' 
def get_queryset(self): 
    city_id = self.kwargs['city'] 
    category_id = self.kwargs['category'] 
    entry = Entry.objects.all().filter(city=city_id).filter(category=category_id) 
    return entry 

urls.py

url(r'^(?P<city>[0-9]+)/(?P<category>[0-9]+)/$', views.EntryListView.as_view(), name='entry'), 

category.html

{% extends 'myapp/base.html' %} 

{% block body %} 

<table> 
{% for new in entry %} 
    <tr> 
     <td> 
      <img src = "{{new.image_url}}"> 
     <br> 
      <b>Name :</b> {{new.name}}<br> 
      {% if new.phone %} 
      <B>Phone No. :</B> {{new.phone}}<br> 
      {% endif %} 
      <b>Address :</b> {{new.address}}<br> 
     </td> 
    </tr> 
{% endfor %} 

{% endblock %} 

models.py

class Entry(models.Model): 
    city = models.ForeignKey(City, on_delete=models.CASCADE) 
    category = models.ForeignKey(Category, on_delete=models.CASCADE) 
    name = models.CharField(max_length=250) 
    phone = models.IntegerField(null=True) 
    address = models.CharField(max_length=250) 
    image_url = models.CharField(max_length=500) 
    def __str__(self): 
     return self.name 
Смежные вопросы