通过混合处理带有自定义 slug 的重复对象
handling duplicate objects with custom slugs via mixins
我们有一个包含两个对象的 Django 应用程序,城市和事件。我们常见的 url 模式是:
app.com/city/name-of-city/event/name-of-event
其中 name-of-city
和 name-of-event
是 slug。例如:
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:
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 并且还可以处理重复事件名称的情况?
谢谢
每个城市的鼻涕虫总是独一无二的,因为您已经设置了 unique_with
属性。但是您没有在查询中使用城市,因此您将获得所有城市的事件 - 这些城市可以使用相同的 slug。您需要在查找中使用城市:
event = get_list_or_404(
Event,
slug=kwargs.get(self.event_slug_url_kwarg),
city__slug=kwargs.get(self.city_slug_url_kwarg)
)
我们有一个包含两个对象的 Django 应用程序,城市和事件。我们常见的 url 模式是:
app.com/city/name-of-city/event/name-of-event
其中 name-of-city
和 name-of-event
是 slug。例如:
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:
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 并且还可以处理重复事件名称的情况?
谢谢
每个城市的鼻涕虫总是独一无二的,因为您已经设置了 unique_with
属性。但是您没有在查询中使用城市,因此您将获得所有城市的事件 - 这些城市可以使用相同的 slug。您需要在查找中使用城市:
event = get_list_or_404(
Event,
slug=kwargs.get(self.event_slug_url_kwarg),
city__slug=kwargs.get(self.city_slug_url_kwarg)
)