I have a model that looks like this:
class Movie(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200)
user = models.ForeignKey(User)
created_on = models.DateTimeField(default=datetime.datetime.now())
class Meta:
ordering = ['-title']
def __unicode__(self):
return self.title
class MovieScreener(models.Model):
screener_asset = models.FileField(upload_to='movies/screeners/')
movie = models.ForeignKey(Movie)
class MovieTrailer(models.Model):
trailer_asset = models.FileField(upload_to='movies/trailers/', blank=True, null=True)
description = models.TextField()
movie = models.ForeignKey(Movie)
class MoviePoster(models.Model):
poster_asset = models.FileField(upload_to='movies/posters/', blank=True, null=True)
movie = models.ForeignKey(Movie)
And my forms look like this:
class MovieForm(forms.ModelForm):
class Meta:
model = Movie
exclude = ('user','created_on')
class MovieScreenerForm(forms.ModelForm):
class Meta:
model = MovieScreener
exclude = ('movie',)
class MovieTrailerForm(forms.ModelForm):
class Meta:
model = MovieTrailer
exclude = ('movie',)
class MoviePosterForm(forms.ModelForm):
class Meta:
model = MoviePoster
exclude = ('movie',)
And here is my views.py (this is where it looks ugly)
@login_required
def create_movie(request, template_name="explore/create_movie.html"):
if request.method == 'POST':
movie_form = MovieForm(data=request.POST)
movie_screener_form = MovieScreenerForm(data=request.POST, files=request.FILES, prefix="a")
movie_trailer_form = MovieTrailerForm(data=request.POST, files=request.FILES, prefix="b")
movie_poster_form = MoviePosterForm(data=request.POST, files=request.FILES, prefix="c")
if movie_form.is_valid() and movie_screener_form.is_valid() and movie_trailer_form.is_valid():
movie_form.instance.user = request.user
movie = movie_form.save()
movie_screener_form.save(commit=False)
movie_screener_form.instance.movie = movie
movie_screener_form.save()
movie_trailer_form.save(commit=False)
movie_trailer_form.instance.movie = movie
movie_trailer_form.save()
movie_poster_form.save(commit=False)
movie_poster_form.instance.movie = movie
movie_poster_form.save()
url = urlresolvers.reverse('explore')
return redirect(url)
else:
movie_form = MovieForm(instance=request.user, label_suffix='')
movie_screener_form = MovieScreenerForm(prefix="a", label_suffix='')
movie_trailer_form = MovieTrailerForm(prefix="b", label_suffix='')
movie_poster_form = MoviePosterForm(prefix="c", label_suffix='')
context = RequestContext(request, locals())
return render_to_response(template_name, context)
My views.py seems very repetitive, is this the right way to do this or is there a better way to do this?
Thanks
J
One thing you could do is move the setting of the movie instance on model forms that require it from the view to the form itself by passing it in as an argument when initializing the form. Here's an example of one implementation, but this can probably be made into a base form class that others can inherit from, saving you from having to do the override in each one individually. None of this code has been tested, I'm just thinking out loud...
If I've understood your design correctly, then:
Is this right?
If my assumptions are right, then you can just have all the fields on the Movie model. (The trailer and poster are already nullable, so they are optional). So you only need one model and one form.
Can't really think of a way in terms of defining the models or forms, but you can cut down on some lines with the following.