代理模型定制

Proxy Model Customization

我有相关类型的代理模型。问题是 ListView 和 DetailView 连接。

课程有所有类型的课程,每门课程必须有相关类型的URL。

这是我的示例代码的完整结构,(模型、视图、url、模板)

#models.py
COURSE_TYPES = (
    ('a', 'Appetizer'),
    ('s', 'Soup and Salad'),
    ('m', 'Main Course'),
    ('d', 'Dessert')
)


class Course(models.Model):
    type = models.CharField(max_length=1, choices=COURSE_TYPES)
    name = models.CharField(max_length=100)
    slug = models.SlugField(blank=True, unique=True)
    thumbnail = models.ImageField(null=True, blank=True)
    description = models.TextField(max_length=1000)

    def get_absolute_url(self):
        return reverse('course', kwargs={'slug':self.slug})
         
class AppetizerManager(models.Manager):
    def get_queryset(self):
        return super(AppetizerManager, self).get_queryset().filter(
            type='a')
      
class MainManager(models.Manager):
    def get_queryset(self):
        return super(MainManager, self).get_queryset().filter(
            type='m')
      
class Appetizer(Course):
    objects = AppetizerManager()
    class Meta:
        proxy = True  
        
class Main(Course):
    objects = MainManager()
    class Meta:
        proxy = True
        

#views.py
class CourseListView(ListView):
    model = Course
    template_name = 'courses.html'
    
class AppetizerDetailView(DetailView):
    model = Appetizer
    template_name = 'appetizer_detail.html'

class MainDetailView(DetailView):
    model = Main
    template_name = 'main_detail.html'

    
#urls.py
urlpatterns = [
    path('courses/', views.CourseListView.as_view(), name='courses'),
    path('appetizer/<slug:slug>/', views.AppetizerDetailView.as_view(), name='appetizer'),
    path('main/<slug:slug>/', views.MainDetailView.as_view(), name='main'),
    ]


#courses.html
<h1>Courses</h1>
{% for course in object_list %}
  <ul>
    <li><a href="{{ course.get_absolute_url }}">{{ course.name }}</a></li>
  </ul>
{% endfor %}

我如何为此正确编辑我的代码?

谢谢。

您可以通过以下方式覆盖基础模型 Course 上的 get_absolute_url 方法:

class Course(models.Model):
    # ...
    def get_absolute_url(self):
        
        # this can be more pythonic, using a dictionary perhaps
        if self.type == 'a':
           viewname = "appetizer"
        elif self.type == 'm':
           viewname = "main"
        # ...
        # continue with other proxy models...
        # ...
        return reverse(viewname, kwargs={'slug':self.slug})

当然,这会在基础 class 和子 class 之间创建一些耦合。