2012-03-03 15 views
2

最近私はdjangoの登録フォームを次のように拡張しようとしましたが、デフォルトの4つのフィールドしか見ることができません。私は行方不明の何かがありますか?djangoでフォームを拡張しますか?

カスタムフォームを作成する場合は、独自の登録バックエンドを作成する必要がありますか?

class RegistrationForm(forms.Form): 

    username = forms.RegexField(regex=r'^\w+$', 
           max_length=30, 
           widget=forms.TextInput(attrs=attrs_dict), 
           label=_(u'Username')) 
    email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict, 
                   maxlength=75)), 
          label=_(u'Email address')) 
    first_name =forms.CharField(widget=forms.TextInput(attrs=attrs_dict),label=_(u'First Name')) 
    last_name =forms.CharField(widget=forms.TextInput(attrs=attrs_dict),label=_(u'Last Name')) 
    password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False), 
           label=_(u'Password')) 
    password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False), 
           label=_(u'Password (again)')) 
    keywords = forms.ModelMultipleChoiceField(queryset=Keyword.objects.all()) 
    #keywords = forms.ModelChoiceField(queryset=Keyword.objects.all()) 

    def clean_username(self): 
     try: 
      user = User.objects.get(username__iexact=self.cleaned_data['username']) 
     except User.DoesNotExist: 
      return self.cleaned_data['username'] 
     raise forms.ValidationError(_(u'This username is already taken. Please choose another.')) 

    def clean(self): 
     if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data: 
      if self.cleaned_data['password1'] != self.cleaned_data['password2']: 
       raise forms.ValidationError(_(u'You must type the same password each time')) 
     return self.cleaned_data 

    def save(self, profile_callback=None): 
     new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'],password=self.cleaned_data['password1'],email=self.cleaned_data['email'],profile_callback=profile_callback) 
    new_profile = UserProfile(user=new_user,username=self.cleaned_data['username'], keywords_subscribed=self.cleaned_data['keywords'],first_name=self.cleaned_data['first_name'],last_name=self.cleaned_data['last_name'],email=self.cleaned_data['email']) 
    new_profile.save()  
     return new_user 

テンプレートコードを追加しました:

テンプレートコードは、参考のために添加されます。これは、登録モジュールにforms.pyから参照しています

<html> 
    <body> 
     <div id="popupLayer_login" style="visibility: visible; position: fixed;"> 
      <div id="content-home" style="width: 700px; margin-left: -300px; top: 60px; position: fixed;"> 
       <br /> 
       {% block title %}<h2 style="margin: 0px; margin-bottom: 20px; text-align: center">Register for an account</h2>{% endblock %} 
       {% block content %} 
       <table style="margin-left: 100px; width: 500px;"> 
        <tbody> 
         <form method='post' action=''> 
          {% csrf_token %} 
          {{ form }} 
          <tr> 
           <td style="border-width: 0px;"></td> 
           <td style="border-width: 0px;"> 
           <input type="submit" value="Send activation email" /> 
           </td> 
          </tr> 
         </form> 
        </tbody> 
       </table> 
       {% endblock %} 
      </div> 
     </div> 
    </body> 
</html> 

これは私urls.py

urlpatterns = patterns('', 
         # Activation keys get matched by \w+ instead of the more specific 
         # [a-fA-F0-9]{40} because a bad activation key should still get to the view; 
         # that way it can return a sensible "invalid key" message instead of a 
         # confusing 404. 
         url(r'^activate/(?P<activation_key>\w+)/$', 
          activate, 
          name='registration_activate'), 
         url(r'^login/$', 
          auth_views.login, 
          {'template_name': 'registration/login.html'}, 
          name='auth_login'), 
         url(r'^logout/$', 
          auth_views.logout, 
          {'template_name': 'registration/logout.html'}, 
          name='auth_logout'), 
         url(r'^password/change/$', 
          auth_views.password_change, 
          name='auth_password_change'), 
         url(r'^password/change/done/$', 
          auth_views.password_change_done, 
          name='auth_password_change_done'), 
         url(r'^password/reset/$', 
          auth_views.password_reset, 
          name='auth_password_reset'), 
         url(r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 
          auth_views.password_reset_confirm, 
          name='auth_password_reset_confirm'), 
         url(r'^password/reset/complete/$', 
          auth_views.password_reset_complete, 
          name='auth_password_reset_complete'), 
         url(r'^password/reset/done/$', 
          auth_views.password_reset_done, 
          name='auth_password_reset_done'), 
         url(r'^register/$', 
          register, 
          name='registration_register'), 
         url(r'^register/complete/$', 
          direct_to_template, 
          {'template': 'registration/registration_complete.html'}, 
          name='registration_complete'), 
         ) 

、私のviews.pyある

def register(request, success_url=None, 
      form_class=RegistrationForm, profile_callback=None, 
      template_name='registration/registration_form.html', 
      extra_context=None): 
    if request.method == 'POST': 
     form = form_class(data=request.POST, files=request.FILES) 
     if form.is_valid(): 
      new_user = form.save(profile_callback=profile_callback) 
      # success_url needs to be dynamically generated here; setting a 
      # a default value using reverse() will cause circular-import 
      # problems with the default URLConf for this application, which 
      # imports this file. 
      return HttpResponseRedirect(success_url or reverse('registration_complete')) 
    else: 
     form = form_class() 

    if extra_context is None: 
     extra_context = {} 
    context = RequestContext(request) 
    for key, value in extra_context.items(): 
     context[key] = callable(value) and value() or value 
    return render_to_response(template_name, 
           { 'form': form }, 
           context_instance=context) 
+1

テンプレートコードは表示できますか? – jpic

+1

フォームがdjango登録フォームから派生していないのはなぜですか? – szaman

+0

@jpicはすでにテンプレートコードを追加しています。 –

答えて

6

実際には外部アプリのコードを変更する必要はありません。あなたが本当に正当な理由がない限り - 明らかにこのケースはそうではありません。これはフォークと呼ばれ、より多くのメンテナンスが必要なため、アップデートを行うため、アップデートを反映する必要があります。

は、コードに触れずに、常に外部アプリを再利用するようにしてください。この場合、コードに触れずに登録フォームを拡張することは完全に可能です。それは、少しブードゥーを必要としていると言いました。ビュー署名でform_class引数の

  1. チェック、問題のビューは、このようなシグネチャがあります:request(request, success_url=None, form_class=RegistrationForm, profile_callback=None, template_name='registration/registration_form.html', extra_context=None)これはまともなアプリのために働くことに注意してください。これは非常にクールです。異なる成功URL、プロファイルコールバック、テンプレート、余分なコンテキスト、最も重要な場合はform_classでビューを再利用できることを意味します。

  2. サブクラス形

作成フォームクラスを渡し、別のURLを作成し、フォームのクラス渡すRegistrationFormから

  • オーバーライドURLを継承する別のフォームを作成しますプロジェクトディレクトリのforms.py:

    from django import forms 
    
    from registration.forms import RegistrationForm 
    
    class ProjectSpecificRegistrationForm(RegistrationForm): 
        keywords = forms.ModelMultipleChoiceField(queryset=Keyword.objects.all()) 
        first_name =forms.CharField(widget=forms.TextInput(attrs=attrs_dict),label=_(u'First Name')) 
        last_name =forms.CharField(widget=forms.TextInput(attrs=attrs_dict),label=_(u'Last Name')) 
    

    次に、のURLにあります。URLは以下のような絶対パス/registration/register/ URLで "registration_register" という名前

    urlpatterns = patterns('', 
        url(r'registration/', include('registration.urls'), 
    ) 
    

    上書き::

    import forms 
    
    urlpatterns = patterns('', 
        url(r'^registration/register/$', 'views.registration.register', { 
         'form_class': forms.ProjectSpecificRegistrationForm}, 'registration_register'), 
        url(r'^registration/', include('registration.urls'), 
    ) 
    

    がここurl() functionがあり

    を何が起こっているのPY、あなたは次のようなものを持っている必要がありますそのような署名:url(regex, view, kwargs=None, name=None, prefix='')。上記の定義では、form_classを持つdictをkwargsに渡しています。したがって、ビューはform_class =あなたのフォームクラスで呼び出されます。あなたが/registration/register/を次回開いたときには、それはあなたのフォームクラスを渡すあなたのURLを、使用するとにかく

    url(r'^registration/register/$', 'views.registration.register', { 
         'form_class': forms.ProjectSpecificRegistrationForm, 
         # provided that you imported SomeModel 
         'extra_context': {'models': SomeModel.objects.all()}}, 'registration_register'), 
    

    :あなたも同じよう余分なコンテキストを追加することができますので、それは実際にはかなり面白いです。あなたもあなたのプロジェクトに本当に固有のものであり、再利用すべき理由を持っていないすべてのコードを置くところproject_specificのようなアプリを作成することができ

    注意。

  • +0

    うわー、本当に良い説明です。 OKを試してみて、戻ってきて受け入れてください。しかし、それは間違いなく私の投票を得る。ありがとう! :D –

    +0

    questionしかし、forms.pyはプロジェクトディレクトリのどこにでも置くことができますか? urls.pyについては、登録urls.pyまたはメインのurls.pyを変更しますか? –

    +0

    私は、外部のアプリケーションでコードを変更しないでください** **を繰り返します! find **あなたのプロジェクトurls.py **は、**外部アプリケーションのURLを**含むべきであり、urlオーバーライド**を上記の** includeの上に追加してください。 forms.pyは、あなたのメインのurls.py **にインポートできる限り、どこでも本当に**できます。 – jpic

    関連する問題