I am starting to learn how to use the generic view. Considering that we`ve got a foreign key to parent. How can I create a child view using Generic View? Would that be the same way we are creating the parentview?
views?.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")
You need to communicate to the child view what the parent is. The common solution is to use nested urls:
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()),
]
Now you can restrict the child to specific a parent in the 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...
Wait, this gets repetitive:
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'