【问题标题】:User specific data in automatic generated forms自动生成表单中的用户特定数据
【发布时间】:2015-03-02 13:41:19
【问题描述】:

我的代码非常简单直接。这些是我的表格

class LearningObjectiveForm( ModelForm ):
  class Meta:
    model = LearningObjective
    fields = ( 'learning_objective', 'topic', )

这是来自我的模板

的sn-p
<form method="POST" action=".">
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="Speichern"/>
</form>

这种形式现在让每个用户都可以访问每个主题。由于该字段通常具有用户限制,因此我不希望显示每个主题,而只显示某个用户的主题。我的模型中针对这个特定案例的结构如下所示

class Trainee( models.Model ):
  user = models.OneToOneField( User )
  first_name = models.TextField()
  last_name = models.TextField()
  education_beginning = models.DateField()
  comment = models.TextField( null = True, blank = True )

class Topic( models.Model ):
  trainee = models.ForeignKey( Trainee )
  topic = models.TextField()

class LearningObjective( models.Model ):
  trainee = models.ForeignKey( Trainee )
  topic = models.ManyToManyField( Topic, blank = True, null = True)
  learning_objective = models.TextField()

还有我的观点

class LearningObjectiveView( LoginRequiredMixin, FormView ):
  form_class = LearningObjectiveForm( user = request.user )
  success_url = reverse_lazy( 'learning_objective' )
  template_name = 'learningobjective.html'

  def get_context_data( self, **kwargs ):
    trainee = Trainee.objects.get( user = self.request.user )
    context = super( LearningObjectiveView, self ).get_context_data( **kwargs )
    context['learningobjective'] = LearningObjective.objects.filter( trainee = trainee.id )
    context['topic'] = Topic.objects.filter( trainee = trainee.id )
    return context

  def form_valid( self, form ):
    self.object = form.save( commit = False )
    if self.request.user.is_authenticated():
      self.object.trainee = Trainee.objects.get( user = self.request.user )
    self.object.save()
    return super( LearningObjectiveView, self ).form_valid( form )

主题应针对受训者。我必须在模板中编写自己的表单还是有这样的方法可以自动生成它?

【问题讨论】:

    标签: django django-forms django-templates


    【解决方案1】:

    您可以在表单初始化函数中修改ModelChoiceField 的查询集属性,这将限制选择并正确验证。

    表单将类似于以下代码

    class LearningObjectiveForm(ModelForm):
      class Meta:
        model = LearningObjective
        fields = ('learning_objective', 'topic',)
    
      def __init__(self, user, *args, **kwargs):
        super(LearningObjectiveForm,self ).__init__(*args,**kwargs)
        self.fields['topic'].queryset = Topic.objects.filter(trainee=user)
    

    然后在表单中确保使用用户LearningObjectiveForm(user=request.user)调用表单

    【讨论】:

    • 请注意,trainee不是User 的外键。
    • 那么你是如何将受训者与用户联系起来的呢?你怎么知道请求用户是哪个实习生?
    • 好吧,是的,这种方法会给你带来很多麻烦。看看扩展用户模型。 docs.djangoproject.com/en/1.7/topics/auth/customizing/…你无法通过这种方式分辨出哪个学员在使用该应用程序。
    • 您需要使用 request 参数调用表单,或者实际上此时最好传入 request.user 对象。这是一个例子stackoverflow.com/questions/1202839/…
    • 好的,所以你使用的是 CBV,它与那个不同(你没有发布任何显示的东西)......搜索如何在 CBV 中获取请求,你将不得不覆盖get_form_class 方法
    【解决方案2】:

    除了 awwester 的回答之外,我还将此添加到我的 视图

    class LearningObjectiveView( LoginRequiredMixin, FormView ):
        form_class = LearningObjectiveForm
        template_name = 'learningobjective.html'
        success_url = reverse_lazy( 'learning_objective' )
    
        def get_context_data( self, **kwargs ):
            trainee = Trainee.objects.get( user = self.request.user )
            context = super( LearningObjectiveView, self ).get_context_data( **kwargs )
            context['learningobjective'] = LearningObjective.objects.filter( trainee = trainee.id )
            context['topic'] = Topic.objects.filter( trainee = trainee.id )
            return context
    
        def get_form_kwargs( self ):
            kwargs = super( LearningObjectiveView , self ).get_form_kwargs()
            kwargs['user'] = self.request.user
            return kwargs
    
        def form_valid( self, form ):
            self.object = form.save( commit = False )
            if self.request.user.is_authenticated():
                self.object.trainee = Trainee.objects.get( user = self.request.user )
            self.object.save()
            return super( LearningObjectiveView, self ).form_valid( form )
    

    get_form_kwargs 将 kwarg 用户与当前用户一起传递给表单。 然后我的Form终于变成了这样:

    class LearningObjectiveForm( ModelForm ):
        def __init__( self, user, *args, **kwargs ):
            trainee = Trainee.objects.get( user = user )
            super( LearningObjectiveForm, self ).__init__( *args, **kwargs )
            self.fields['topic'].queryset = Topic.objects.filter( trainee = trainee.id )
    
        class Meta:
            model = LearningObjective
            fields = ( 'learning_objective', 'topic', )
    

    现在可以正常使用,但如果有多余或不必要的内容,请告诉我:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-25
      • 1970-01-01
      • 2022-07-20
      • 1970-01-01
      • 2012-04-01
      • 1970-01-01
      相关资源
      最近更新 更多