3

カスタムフィールドをdjango-registration登録フォーム/フローに追加するという一見単純な問題に対するさまざまな回答が提供されていることに、私はますます当惑しています。これは、パッケージのデフォルトの文書化された側面であるべきですが (恩知らずに聞こえないように、十分に装備されたパッケージであるというだけです)、問題の解決策は目まぐるしいものです。

デフォルトの登録登録ページに含まれる UserProfile モデル データを取得するための最も簡単な解決策を教えてくれる人はいますか?

アップデート:

私は最終的に、Django Registration 独自のシグナルを使用して、このハッキーな修正を行いました。try空のままにするとチェックボックスが何も返さないことがわかったため、ブール値を処理する POST 属性で使用する必要があったため、特に醜いです。

これを改善するためのアドバイス、またはベストプラクティスをいただければ幸いです。

私のアプリ/models.py

from registration.signals import user_registered
from django.dispatch import receiver

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    event_commitments = models.ManyToManyField(Event, null=True, blank=True)
    receive_email = models.BooleanField(default=True)

@receiver(user_registered)
def registration_active_receive_email(sender, user, request, **kwargs):
    user_id = user.userprofile.id
    user = UserProfile.objects.get(pk=user_id)

    try:
        if request.POST['receive_email']:
            pass
    except:
        user.receive_email = False
        user.save()

登録アプリ / forms.py

class RegistrationForm(forms.Form):

    # default fields here, followed by my custom field below

    receive_email = forms.BooleanField(initial=True, required=False)

ありがとう

4

2 に答える 2

2

あなたが持っているものは、実行可能なアプローチのように見えます。

私は django-registration コードに目を通し、登録ビューの次のコメントに基づいて、別の解決策を思いつきました。これがよりクリーンであるかどうかは完全にはわかりませんが、信号のファンでない場合はこれで十分です。これにより、より多くのカスタマイズを行う場合にも、はるかに簡単な方法が提供されます。

# from registration.views.register:
"""
...
2. The form to use for account registration will be obtained by
   calling the backend's ``get_form_class()`` method, passing the
   ``HttpRequest``. To override this, see the list of optional
   arguments for this view (below).

3. If valid, the form's ``cleaned_data`` will be passed (as
   keyword arguments, and along with the ``HttpRequest``) to the
   backend's ``register()`` method, which should return the new
   ``User`` object.
...
"""

カスタム バックエンドを作成し、前述のメソッドをオーバーライドできます。

# extend the provided form to get those fields and the validation for free
class CustomRegistrationForm(registration.forms.RegistrationForm):
    receive_email = forms.BooleanField(initial=True, required=False)

# again, extend the default backend to get most of the functionality for free
class RegistrationBackend(registration.backends.default.DefaultBackend):

    # provide your custom form to the registration view
    def get_form_class(self, request):
        return CustomRegistrationForm

    # replace what you're doing in the signal handler here
    def register(self, request, **kwargs):
        new_user = super(RegistrationBackend, self).register(request, **kwargs)
        # do your profile stuff here
        # the form's cleaned_data is available as kwargs to this method
        profile = new_user.userprofile
        # use .get as a more concise alternative to try/except around [] access
        profile.receive_email = kwargs.get('receive_email', False)
        profile.save()
        return new_user

カスタム バックエンドを使用するには、個別の URL を指定できます。デフォルトの URL を含める前に、カスタム バックエンドを指す 2 つの conf を記述します。URL は定義された順序でテストされるため、デフォルトを含める前にこれら 2 つを定義すると、デフォルトのものをテストする前にこれら 2 つがキャプチャされます。

url(r'^accounts/activate/(?P<activation_key>\w+)/$',
    activate,
    {'backend': 'my.app.RegistrationBackend'},
    name='registration_activate'),
url(r'^accounts/register/$',
    register,
    {'backend': 'my.app.RegistrationBackend'},
    name='registration_register'),

url(r'^accounts/', include('registration.backends.default.urls')),

ドキュメントには実際にこれらすべてが説明されていますが、特にアクセスしやすいわけではありません (readthedocs はありません)。それらはすべてプロジェクトに含まれており、ここで閲覧していました。

于 2012-10-04T18:32:16.733 に答える
1

私は最終的に Django Registration 独自のシグナルを使用して、この修正を行いました。

ある時点で、try/except フローをクリーンアップします。dokkaebi は、チェックボックスが空のままになっている場合の request.GET パラメータを評価できる可能性があることも上記で指摘しています。

私のアプリ/models.py

from registration.signals import user_registered
from django.dispatch import receiver

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    event_commitments = models.ManyToManyField(Event, null=True, blank=True)
    receive_email = models.BooleanField(default=True)

@receiver(user_registered)
def registration_active_receive_email(sender, user, request, **kwargs):
    user_id = user.userprofile.id
    user = UserProfile.objects.get(pk=user_id)

    try:
        if request.POST['receive_email']:
            pass
    except:
        user.receive_email = False
        user.save()

登録アプリ / forms.py

class RegistrationForm(forms.Form):

    # default fields here, followed by my custom field below

    receive_email = forms.BooleanField(initial=True, required=False)
于 2012-10-05T00:46:54.967 に答える