Numerous Django models, one form

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 view.py (here 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

+4
source share
3 answers

It’s impossible to think of a way to define models or forms, but you can cut some lines as follows.

 mfs = [movie_screener_form, movie_trailer_form, movie_poster_form] for mf in mfs: mf.save(commit=False) mf.instance.movie = movie mf.save() 
+3
source

One thing you can do is move the setting of the movie instance to the model form, which requires it from the presentation to the form itself, passing it as an argument when initializing the form. Here is an example of one implementation, but this can probably be done in the base class of the form, which others can inherit, eliminating the need to override each one individually. None of this code has been tested, I just think 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() 
+3
source

If I understand your design correctly, then:

  • Every movie has a screener
  • There is never more than one screening in films
  • A movie may have a trailer
  • There is never more than one trailer in movies
  • The movie may have a poster.
  • There has never been more than one poster in movies

Is it correct?

If my assumptions are correct, you can just have all the fields in the movie model. (The trailer and poster are already nullified, so they are optional). Therefore, you only need one model and one shape.

0
source

Source: https://habr.com/ru/post/1385218/


All Articles