overriding default templates of django-allauth - django

I used this social registration/signup library django allauth for a project of mine. How do i customize the default templates and forms to give a better look and feel?

Assuming you have set a project level templates directory using the TEMPLATE_DIRS setting like:
TEMPLATE_DIRS = [
os.path.join(PROJECT_DIR, 'templates'),
]
You should be able to copy all of the folders shown here into that directory and edit them as you need. Most of the templates seem to be filling a {% block content %} block, so it's probably easiest if your site_base.html template defines that block somewhere.
If you haven't set TEMPLATE_DIRS, you can do the same thing, but copy the template folders into the templates directory of one of your apps. I prefer to set TEMPLATE_DIRS and keep the main site templates like base.html there, since they don't really belong to a particular app, but that's really just a preference; the template loader should find them either way.

In your views:
from allauth.account.views import SignupView, LoginView
class MySignupView(SignupView):
template_name = 'my_signup.html'
class MyLoginView(LoginView):
template_name = 'my_login.html'
Do pay attention to the examples and docs for structuring your own templates.
Watch this piece in the example templates though:
<form id="signup_form" method="post" action="{% url 'account_signup' %}">
I had to remove the URL link to make it work properly in my own template:
<form id="signup_form" method="post" action="">'

the latest version of all-auth on github has its templates outside, however the one on Pypi is not, all you need to do is clone the repo in your project directory and override the templates. As simple as that.

Use the same logic as overriding admin templates.

Have a look at the example application; it has a templates folder that indicates the layout of the necessary templates

All of these are good suggestions.
Most of these ought to work.
The only thing that worked for me, though, was to include my own templates in "project/app/templates/account/" and make sure that "django-allauth" gets listed in INSTALLED_APPS after my own app.
I discovered this here.

To customize django-allauth after installing it, copy it from site-packages and paste it in your project apps directory. In this way the default allauth app and its templates being used will be those in your project's allauth app. Then if you want to modify signup.html of socialaccount then go to apps\allauth\templates\socialaccount\signup.html and modify it by editting inside 'block content' tag:
{% block content %}
// your customized html for signup form
{% endblock %}
Hope this will help you.

Related

Accessing custom directory under static directory in Django

I am learning Django.
I know how to add use {% static "abc/xyz" %} in templates.
But now I want to use something similar in views.py file.
For example project->my_app->static->resources->abc.json is the file I need to access in the views.py of my_app.
When I tried f = open('resources/abc.json') it didn't work.
How do I do it correctly?

Failed to check INSTALLED_APPS in django template

I am trying to load some HTML element in my django template, if a specific app is defined in my settings.py file. But it doesn't work. The if statement behaves like the app doesn't exist:
{% if 'myapp.edit_data' in INSTALLED_APPS %}
<p> dfsdfsdf </p>
{% endif %}
I also tried with other apps and I get the same behavior. What am I missing?
You can't automatically access settings like INSTALLED_APPS in the template. You have to add it to the template context.
For example, in the view, you could do:
from django.conf import settings
def my_view(request):
return render(request, 'my_template.html', {'INSTALLED_APPS': settings.INSTALLED_APPS})
If this check was in the base template, then you might want to create a template context processor instead of changing every view.

Using static files in custom 404/500 pages in Django

I would like to use some custom CSS and images on my custom 404/500 pages that I made. Django doesn't include the STATIC_URL variable in those pages though.
What would be the best way to accomplish this? I also tried making a custom 404/500 view and rendering an arbitrary HTML file but it didn't work out so great.
Here's how I would do it:
# urls or settings
handler500 = 'mysite.views.server_error'
# views
from django.shortcuts import render
def server_error(request):
# one of the things ‘render’ does is add ‘STATIC_URL’ to
# the context, making it available from within the template.
response = render(request, '500.html')
response.status_code = 500
return response
It's worth mentioning the reason Django doesn't do this by default:
“The default 500 view passes no variables to the 500.html template and is rendered with an empty Context to lessen the chance of additional errors.”
-- Adrian Holovaty, Django documentation
I run into the same problem and found a solution which doesn't need custom templates or handlers. From Django 1.4 on you can use the tags get_media_prefix and get_static_prefix to access MEDIA_URL and STATIC_URL when they are not in the context.
In my particular case (Django 1.5), I wanted to access some static images in my page 500.html. I just added at the beginning of the template
{% load static %}
and then obtained the media and static urls with these tags
<img src="{% get_media_prefix %}logo.png">
<img src="{% get_static_prefix %}img/error_pages/error.png" style="height:235px;">
You can find the official documentation here: https://docs.djangoproject.com/en/1.5/ref/templates/builtins/#get-static-prefix
I believe you're just going to have to override the default 404/500 error handling. This should get you started:
http://docs.djangoproject.com/en/dev/topics/http/views/#customizing-error-views

NoReverseMatch at /, u'opts|admin_urlname' is not a registered namespace Django 1.4.1

Django newbie here. Following the documentation, I am trying the following to get a link to the admin site from the homepage of the public site I'm building:
{% load admin_urls %}
<p>Go to the admin.</p>
I am getting the error:
NoReverseMatch at /
u'opts|admin_urlname' is not a registered namespace
I am including the URLs properly:
url(r'^admin/', include(admin.site.urls)),
My template loaders are in the right order.
I've tried a few different variations on this, and they all throw namespace errors.
Any ideas? Thanks!
After 30 minutes with Daniel Roseman / Django docs in one screen and my code in the other, I come up with this simple solution:
In your views.py, add the opts context with the _meta of the model (that includes the required app_label and model_name):
class YourModelDetailView(DetailView):
def get_context_data(self, **kwargs):
context = super(YourModelDetailView, self).get_context_data(**kwargs)
context["opts"] = YourModel._meta
return context
In your templates:
{% url opts|admin_urlname:'change' object.pk %}
Where change can be any action in the reverse admin urls documentation page.
While the above answers were helpful about the code I was calling, there is a much easier way. I'm using this instead:
{% url 'admin:index' %}
This works for custom admin views as well, like:
{% url 'admin:myapp_mymodel_<keyword>' object.id %}
Where keyword is from the named parameters listed here (i.e. add, change, delete).
You are almost certainly using the released 1.4 version, rather than the development version. As the documentation for that version shows, you need to use {% load url from future %} before you can use that syntax.

Add links to navigation based on INSTALLED_APPS

I have a project that has a number of apps. These apps translate into modules that perform different functions for the end user.
Now each deployment of the project may have certain apps enabled or disabled.
What I'd like to achieve is a navigation list of links that only displays links for apps that are in INSTALLED_APPS.
For example deployment 1 has App1 and App2 listed in INSTALLED_APPS so would have a navigation something like this:
Link to App1's view
Link to App2's view
And deployment 2 has App2 and App3 installed so should show a navigation something like this:
Link to App2's view
Link to App3's view
Without having a navigation defined in a base template and editing it for each deployment, I can't see a way of doing this. Even by using { block.super }, this seems to not allow 2 apps to be installed as each child template would append to the parent.
This is strictly from the top of my head, so it may not be the "best" or most appropriate way.
First, if you're going to rely on INSTALLED_APPS you should actually implement something along the lines of:
MY_INSTALLED_APPS = (
'app1',
'app2',
)
INSTALLED_APPS = (
# other installed apps
) + MY_INSTALLED_APPS
Then, instead of having to figure out which of the items in INSTALLED_APPS are yours and which are third-party, you just use MY_INSTALLED_APPS instead for things like building your menus.
Second, in Django, apps aren't tied to views in any meaningful way. There's no concept of a "default" view, and you can't simply link to an app. However, you can some what achieve this idea through the use of namespaces and a convention for view naming, specifically, all your apps will at least have a urlpattern named "index", for example.
Then, in your urls.py you create urlpatterns like:
url(r'^app1/', include('app1.urls', namespace='app1', app_name='app1'),
url(r'^app2/', include('app2.urls', namespace='app2', app_name='app2'),
# etc
In each app, you create a urls.py that has at least one urlpattern:
url(r'^$', some_view, name='index'),
This means that the going to /app1/ in your browser would then load some_view and you can reference this view in your code with a name like: app1:index.
The tricky part is using this in your templates. Django 1.5 will add the ability to use context variables in the {% url %) tag for the view name. As of Django 1.3, you can use this behavior as well via {% load url from future %}. However, even that only gets you part-way to what you need.
In your template, you'll need to loop through the values of MY_INSTALLED_APPS and construct the links. The following should work in Django 1.3-1.4 via {% load url from future %} or Django 1.5:
{% for app in apps %}
{{ app }}
{% endfor %}
The other way to accomplish this is with a template filter, which is your only option in Django <1.3, and may still be preferable in later versions. Something like:
#register.filter
def default_url_for_app(app):
return reverse(app+':index')
And, in your template:
{% for app in apps %}
{{ app }}
{% endfor %}
You can simple import your settings.py file and iterate over the INSTALLED_APPS list.
from django.conf import settings
for installed_app in settings.INSTALLED_APPS:
But I'm also in doubt if this is a smart decision to implement your application as such.
What you really want here is some kind of app registration system. That is, for each app that's loaded (ie included in INSTALLED_APPS), register its homepage with the list of links.
Rather than doing all this automatically, I would follow the example of the admin application and get each app to call a register function on first load. You could do this in the models.py, for example, since you know that will be imported by Django on startup. The register function would take the app name and the url and build a dictionary which could then be passed to each template via a context processor.