2

I tried overriding a django-recaptcha template without any luck. What am I doing wrong? I am aware of Override templates of external app in Django, but it is outdated. Thanks!

django-recaptcha file structure

Lib/
--site-packages/
----captcha/
------templates/
--------captcha/
----------includes/
------------js_v2_checkbox.html

my project file structure

project/
----templates/
--------captcha/
------------includes/
----------------js_v2_checkbox.html

settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
konichiwa
  • 532
  • 1
  • 5
  • 23

2 Answers2

1

You have two options:

(1) In your settings, rearrange INSTALLED_APPS as follows:

INSTALLED_APPS = [
    ...
    'project',
    ...
    'captcha',
    ...
]

since the template loader will look in the app’s templates directory following the order specified by INSTALLED_APPS, you're template will be found first.

or

(2) List project's templates folder in TEMPLATES[0]['DIRS'] as follows:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        ...
    },
]

Since, DIRS is searched before APP_DIRS, you're template will be found first.

References:

https://docs.djangoproject.com/en/3.0/howto/overriding-templates/

Another possible solution

I notice now that captcha/includes/js_v2_checkbox.html is included by captcha/widget_v2_checkbox.html.

I'm not sure about what happens exactly when widget_v2_checkbox.html is loaded from captcha module ... so I would duplicate the "including" widget_v2_checkbox.html as well into your project's templates folder.

You might also decide to copy the full "templates/captcha" folder contents into you project, for consistency.

Just keep an eye on possibile future changes of those templates when upgrading the captcha module.

Mario Orlandi
  • 5,629
  • 26
  • 29
  • Could this be because I am using both template folder in project root and app template folders to override templates? – konichiwa Apr 05 '20 at 07:35
  • To narrow down things, I suggest to set TEMPLATES[{ ...DIRS': [], 'APP_DIRS': True, ... and try again solution (1). Do you get any error with `python manage.py check` ? Does it work ? Please let me know, I will suggest more tests afterward – Mario Orlandi Apr 05 '20 at 07:57
  • No errors after `check` but my Django seems not to care at all... – konichiwa Apr 05 '20 at 08:03
  • I would check the order followed by Django in template folders navigation. One way to do this is: rename "js_v2_checkbox.html" as "js_v2_checkbox.html.bak" in both captcha and project modules. You will receive a runtime error, and having settings.DEBUG = True a detailed explanation of what happens – Mario Orlandi Apr 05 '20 at 08:11
  • I added an alternative approach to my original suggestion .. have a look ;) – Mario Orlandi Apr 05 '20 at 08:29
  • My project/templates folder is missing: https://i.imgur.com/gveTMJj.png. It's looking in my `company` and `home` apps... – konichiwa Apr 05 '20 at 19:38
  • I tried creating a new app with a `templates` folder. That worked. I have feeling `APP_DIRS': True` excludes project root `templates` folder.... – konichiwa Apr 05 '20 at 23:11
  • As long as you list it in settings.INSTALLED_APPS, the project should be treated as an app. Is it a valid Python module ? Can you issue `python manage.py shell` and from there `import project` ? Does it work ? However, since you managed to solve the issue with a separate app, I guess your problem is over ;) – Mario Orlandi Apr 06 '20 at 05:37
0

Can I see the order of your INSTALLED_APPS? It could be that you are rendering django-recaptcha captcha templates before you render your own templates. To fix this you could move the the external app captcha last in the INSTALLED_APPS list.

Dean Elliott
  • 1,245
  • 1
  • 8
  • 12