2016-07-12 3 views
2

私のDjangoウェブサイトのすべてのページにフッターリンク「フィードバック/質問」があります。新しい人がサイトに来てそのリンクをクリックすると、プルダウンのあるフォームに誘導され、フィードバックがあるのか​​どうか、自分のメールアドレスとフィードバックや質問のフィールドが表示されます。ページには、認証されていないすべてのユーザーに表示される単純なヘッダーが表示されます。一方、サイトメンバーがサインインして認証されている場合、同じフォームが表示されますが、電子メールフィールドはありません(私はすでに電子メールアドレスを知っているので)、サイトの内部ナビゲーションバー、ボタンなどを含む別の認証ヘッダー自分のモデルのフォームを持っているでしょうDjangoモデルの継承を使用する場合、この冗長性を避けるにはどうすればよいですか?

class AnonFeedbackQuestion(FeedbackQuestion): 
    email = models.EmailField(...) 
    class Meta: 
    db_table = anon_feedback_question 

class AuthFeedbackQuestion(FeedbackQuestion): 
    user = models.ForeignKey(User, related_name="user") 
    class Meta: 
    db_table = auth_feedback_question 

これらの2つのクラスを:

class FeedbackQuestion(models.Model): 
    submission_type = ... (type, i.e. feedback or question) 
    submission_text = ... (actual feedback or question) 
    ... 
    class Meta: 
    abstract = True 

は、その後私は2つの別々の具体的な子クラスを作成したい:

私の最初に考えたのは、抽象クラスFeedbackQuestionを作成することでした。

class AnonFeedbackQuestionForm(ModelForm): 
    class Meta: 
    model = AnonFeedbackQuestion 
    fields = ['submission_type', 'submission_text', 'email'] 

class AuthFeedbackQuestionForm(ModelForm): 
    class Meta: 
    model = AuthFeedbackQuestion 
    fields = ['submission_type', 'submission_text'] 

私はforsee問題は、私はフィードバックフォームを表示する私の見解では次のことを行う必要がありますということです。

たフォームを識別するために、これらのif/then /他のブロックを繰り返すこと
def get_feedback_questions(request, template): 
    if request.method == 'POST': 
    ... 
    if request.user.is_authenticated(): 
     form = AuthFeedbackQuestionForm(request.POST) 
    else: 
     form = AnonFeedbackQuestionForm(request.POST) 
    if form.is_valid(): 
     (process form) 
     ... 
    else: 
    if request.user.is_authenticated(): 
     form = AuthFeedbackQuestionForm(request.POST) 
    else: 
     form = AnonFeedbackQuestionForm(request.POST) 
    ... 
    context = {'form': form} 
    return render(request, template, context) 

使用するのはむしろ控えめであるように見える。これを行うためのより良い、よりクリーンな "Django"の方法はありますか?

ありがとう!

答えて

1

私はあなたのモデルをサブクラス化しないだろう - それはあなただけblank=Truenull=Trueuser属性だけでなく、一つのモデルにemail属性を含めることができ、匿名の質問だ場合:あなたが追加することができます。この方法で

class FeedbackQuestion(models.Model): 
    submission_type = ... (type, i.e. feedback or question) 
    submission_text = ... (actual feedback or question) 
    email = models.EmailField(..., blank=True, null=True) 
    user = models.ForeignKey(User, related_name="user", blank=True, null=True) 
    ... 
    class Meta: 
     abstract = True 

匿名ユーザーのフィードバック/質問の場合はemail、認証されている場合はuserのいずれかです。

は、その後、私は(this answerを参照)電子メールフィールドを含むいずれかに自分のフォームを組み合わせたが、ユーザーが認証されている場合に応じて、電子メールのフィールドを削除したい:

def __init__(self, *args, **kwargs): 
    self.user = kwargs.pop('user', None) 
    super(UserForm, self).__init__(*args, **kwargs) 
    if self.user: 
     # For logged-in users, email field not necessary 
     self.fields.pop('email') 
    else: 
     # Otherwise, the field needs to be required 
     self.fields['email'].required = True 

を次に、あなたはあなたを確認する必要がありますフォームのデータを整理する際にユーザーを適切に作成してください(たとえば、電子メールアドレスがまだ取得されていないことなど)。

+0

ありがとうございますが、このソリューションは2つの理由でうまく機能しません。 #1電子メールフィールドが空白/ヌルの場合、匿名ユーザーが電子メールなしでフォームを送信すると、電子メールフィールドにエラーは表示されません。 #2電子メールフィールドを必須にして#1を修正し、認証されたユーザーが他のフィールドにエラーのあるフォームを送信すると、電子メールフィールドが再度表示され、値がないためエラーとしてフラグが立てられます。私は他の解決策を探し続けています。 – William

+0

@Robertは、必要に応じてフィールドを設定するかどうかは、モデルレベルではなく、フォームレベルにする必要があります。それはあなたの問題の第1を解決するはずです。 2番は問題ではありません。何があっても、2つの可能性しか持たないはずです:フィールドが存在し、必須であるか、存在しないかのいずれかです。私の更新された答えを参照してください、意味がありますか? – YPCrumble

+0

@YPCrumbleなぜモデルをサブクラス化しないのでしょうか? –

関連する問題