如何为 child 使用通用视图

How to use Generic View for a child

我开始学习如何使用通用视图。考虑到我们有 parent 的外键。如何使用通用视图创建 child 视图? 这与我们创建 parent 视图的方式相同吗?

浏览量?.py

class ChildCreateView(generic.CreateView):
    template_name = "app/create_child.html"
    model = Child
    form_class = ChildForm
    success_url = reverse_lazy("app:index_child")

models.py

class Parent(models.Model):
    pass

class Child(models.Model):
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE)

views1.py

class ParentCreateView(generic.CreateView):
    template_name = "app/create_parent.html"
    model = Parent
    form_class = ParentForm
    success_url = reverse_lazy("app:index_parent")

您需要向子视图传达父视图是什么。常见的解决方案是使用嵌套网址:

urlpatterns = [
    path("/app/parents/", ParentListView.as_view()),
    path("/app/parents/<int:parent_id>/", ParentDetailView.as_view()),
    path("/app/parents/<int:parent_id>/children/", ChildListView.as_view()),
    path("/app/parents/<int:parent_id>/children/<int:child_id>/", ChildDetailView.as_view()),
]

现在您可以在 ChildDetailView 中将子项限制为特定的父项:

class ChildDetailView(generic.DetailView):
    model = Child
    pk_url_kwarg = 'child_id'

    def get_queryset(self, queryset):
        qs = super().get_queryset(queryset)
        return qs.filter(parent__pk=self.kwargs['parent_id'])

class ChildCreateView(generic.CreateView):
    model = Child
    pk_url_kwarg = 'child_id'

    def get_queryset(self, queryset):
        qs = super().get_queryset(queryset)
        return qs.filter(parent__pk=self.kwargs['parent_id'])

class ChildUpdate...

等等,这会重复:

class NestedParentMixin(generic.base.SingleObjectMixin):
    parent_lookup = 'parent__pk'
    parent_url_kwarg = 'parent_id'

    def get_queryset(self, queryset):
        qs = super().get_queryset(queryset)
        filter_kwargs = {self.parent_lookup: self.kwargs[self.parent_url_kwarg]}
        return qs.filter(**filter_kwargs)


class ChildDetailView(NestedParentMixin, generic.DetailView):
    model = Child
    pk_url_kwarg = 'child_id'

class ChildUpdateView(NestedParentMixin, generic.UpdateView):
    model = Child
    pk_url_kwarg = 'child_id'

class SiblingDetailView(NestedParentMixin, generic.DetailView):
    model = Sibling
    pk_url_kwarg = 'sibling_id'