Django多种模式,一种形式

时间:2011-12-07 21:29:57

标签: 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似乎非常重复,这是正确的方法吗?还是有更好的方法来做到这一点?

由于

J

3 个答案:

答案 0 :(得分: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()

答案 1 :(得分: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()

答案 2 :(得分:0)

如果我已正确理解您的设计,那么:

  • 每部电影都有一个筛选器
  • 电影永远不会有一个以上的筛选者
  • 电影可能有预告片
  • 电影永远不会有多个预告片
  • 电影可能有海报
  • 电影永远不会有一张海报

这是对的吗?

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