4

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

3 Answers 3

3

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.

mfs = [movie_screener_form, movie_trailer_form, movie_poster_form]

for mf in mfs:
    mf.save(commit=False)
    mf.instance.movie = movie
    mf.save()
Sign up to request clarification or add additional context in comments.

Comments

3

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...

class MovieScreenerForm(forms.ModelForm): 
    class Meta:
        model = MovieScreener
        exclude = ('movie',)

    def __init__(self, movie, *args, **kwargs):
        super(MovieScreen, self).__init__(*args, **kwargs)
        self.movie = movie

    def save(self, commit=True):
        instance = super(MovieScreenerForm, self).save(commit=False)
        instance.move = self.movie
        instance.save()

Comments

0

If I've understood your design correctly, then:

  • Every movie has a screener
  • Movies never have more than one screener
  • A movie might have a trailer
  • Movies never have more than one trailer
  • A movie might have a poster
  • Movies never have more than one poster

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.