2011-12-07 159 views
4

我有一个模型,看起来像这样:Django的多个模型,一种形式

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) 

而且我的形式是这样的:

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',) 

这里是我的views.py(这是哪里它看起来丑陋)

@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) 

我views.py似乎很重复,这是做的正确方法还是有更好的方式来做到这一点?

感谢

Ĵ

回答

3

真的不能想办法在定义模型或形式的条款,但你可以削减一些线路与以下。

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

有一两件事你可以做的是继续前进需要它从视图的形式本身在初始化时,将它作为一个参数模型形式的电影实例的设置形成。下面是一个实现的例子,但是这可能会成为其他人可以继承的基本表单类,从而使您无需单独进行重写。这段代码没有经过测试,我只是想大声...

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() 
0

如果我理解正确的设计,则:

  • 每部影片都有一个筛选
  • 电影永远不会有一个以上的筛选
  • 电影可能有一个拖车
  • 电影从来没有超过一个拖车
  • 电影可能有一个海报
  • 电影从来没有超过一个海报

这是正确的吗?

如果我的假设是正确的,那么你可以在电影模型中拥有所有的字段。 (预告片和海报已经可以空,所以它们是可选的)。所以你只需要一个模型和一个表单。