обработка дубликатов объектов с помощью пользовательских блоков с помощью mixins

#django #django-models #django-views #django-urls #slug

#django #django-модели #django-представления #django-urls #slug

Вопрос:

у нас есть приложение django с двумя объектами, городами и событиями. общим шаблоном URL для нас было бы:

app.com/city/name-of-city/event/name-of-event где name-of-city и name-of-event — слагаемые. пример:

 class City(models.Model):
      name = models.CharField(max_length=100, unique=True)
      slug = AutoSlugField(populate_from='name', always_update=True, unique=True, sep='-', max_length=255)
      ...
  

события получают свой слаг таким же образом в модели событий:

 slug = AutoSlugField(populate_from='name', always_update=True, unique_with='city', sep='-', max_length=255)
  

проблема, с которой мне трудно разобраться, заключается в том, как обрабатывать экземпляр, в котором в одном городе происходит несколько событий с одинаковым именем.

mixins.py

 class CityMixin(object):
    city_slug_url_kwarg = 'slug'
    city = None

    def fetch_city(self, request, *args, **kwargs):
        if not self.city:
            self.city = get_object_or_404(
                City, slug=kwargs.get(self.city_slug_url_kwarg))
        return self.city

    def get_context_data(self, **kwargs):
        kwargs.setdefault('city', self.city)
        return super(CityMixin, self).get_context_data(**kwargs)

    def dispatch(self, request, *args, **kwargs):
        """
        Sets 'city' within the view
        """
        self.city = self.fetch_city(request, *args, **kwargs)
        return super(CityMixin, self).dispatch(request, *args, **kwargs)


class EventMixin(CityMixin):
    city_slug_url_kwarg = 'city_slug'
    event_slug_url_kwarg = 'slug'
    event = None

    def fetch_event(self, request, *args, **kwargs):

        if not self.event:
            event = get_list_or_404(
                Event, slug=kwargs.get(self.event_slug_url_kwarg))

        return self.event

    def dispatch(self, request, *args, **kwargs):
        """
        Sets 'city' and 'event' within the view
        """
        user = request.user
        self.city = self.fetch_city(request, *args, **kwargs)
        self.event = self.fetch_event(request, *args, **kwargs)
        if self.event.city != self.city:
            raise Http404

        return super(EventMixin, self).dispatch(request, *args, **kwargs)
  

если я запрашиваю событие с:

 event = get_object_or_404(Event, slug=kwargs.get(self.event_slug_url_kwarg))
  

он выдаст ошибку (MultipleObjectsReturned), если существует несколько событий с одинаковыми именами.

если я запрашиваю событие с:

 event = get_list_or_404(Event, slug=kwargs.get(self.event_slug_url_kwarg))
  

и есть идентичные события, приложение не знает, какой объект или индекс в списке является правильным объектом.

существует ли метод, который гарантирует, что запрашивается правильный объект obj, который также может обрабатывать случай повторяющихся имен событий?

Спасибо

Комментарии:

1. Почему должно быть несколько событий с одинаковым именем? У вас есть unique_with='city' в вашем autoslugfield.

2. в одном городе (например, в Лондоне) может быть создано несколько событий с названием «Коктейльная вечеринка», и может быть «Коктейльная вечеринка» во многих разных городах

Ответ №1:

Слагаемые всегда будут уникальными для каждого города, потому что вы установили этот unique_with атрибут. Но вы не используете город в запросе, поэтому вы получите события для всех городов, которые могут использовать один и тот же слаг. Вам нужно использовать город в поиске:

 event = get_list_or_404(
    Event,
    slug=kwargs.get(self.event_slug_url_kwarg),
    city__slug=kwargs.get(self.city_slug_url_kwarg)
)