I have 2 multi-table inherited models like these:
class Post(models.Model):
title = models.CharField(max_length=100, blank=True, null=True)
text = models.TextField(blank=True, null=True)
location = models.PointField()
...
class BlogPost(Post):
blog = models.ForeignKey(Blog)
Similarly, form class for BlogPost also inherits from PostForm class:
class PostForm(MapModelForm):
...
class Meta:
model = Post
def clean(self):
...
class BlogPostForm(PostForm):
class Meta:
model = BlogPost
I used to handle create / update for both models in 2 non-class-based views. To make things DRY, I decided to give Django's class-based generic views a try. But due to the lack of examples and user unfriendliness of the related documents and variety of approaches, I am confused.
The idea is to have class based form views for the Post
model and inherit them for the BlogPost
. How should I tailor the view classes?
Should I have separate PostCreate and PostUpdate views? Then the two classes are almost identical and not DRY at all.
Should I have a single FormView
for both update / create of a post? It works for creation but I couldn't figure out how to do this for for update.
Should I build custom view (or two views for create / update) using provided mixin classes instead of inheriting from the views directly?
You're right that the class-based view documentation is rather primitive. No doubt it will improve, but for the moment you need to be prepared to experiment and to read the source.
You are trying to do two things:
It's important to tackle these one at a time. Figure out the right class hierarchy first, and only then figure out how to factor out the repetition.
Let's have a go. Your class hierarchy is going to look something like this:
from django.views import generic
class PostCreateView(generic.CreateView):
form_class = PostForm
model = Post
class PostUpdateView(generic.UpdateView):
form_class = PostForm
model = Post
class BlogPostCreateView(generic.CreateView):
form_class = BlogPostForm
model = BlogPost
class BlogPostUpdateView(generic.UpdateView):
form_class = BlogPostForm
model = BlogPost
This involves a lot of repetition, but it's clear now how to factor out some of it:
from django.views import generic
class PostView(generic.FormView):
form_class = PostForm
model = Post
class PostCreateView(PostView, generic.CreateView): pass
class PostUpdateView(PostView, generic.UpdateView): pass
class BlogPostView(PostView):
form_class = BlogPostForm
model = BlogPost
class BlogPostCreateView(BlogPostView, generic.CreateView): pass
class BlogPostUpdateView(BlogPostView, generic.UpdateView): pass
And if you're still unhappy with the amount of repetition here, you can further automate the construction of these classes (using type
to create classes at runtime). That's probably a step too far, though, until you're completely comfortable with the use of class-based views.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With