url-tag for url include - django

i use the set_language redirect view form from the docs.
urls.py
urlpatterns += patterns('',
(r'^i18n/', include('django.conf.urls.i18n')),
)
template:
<form action="/i18n/setlang/" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language">
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}">{{ language.name_local }} ({{ language.code }})</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
Which is the right syntax to replace the action attribute "/i18n/setlang/" with the url-template-tag?
EDIT:
I found the right url in the include (thanks to Daniel!):
<form action="{% url django.views.i18n.set_language %}" method="post">

As the documentation says, you can enter the full path of a view as the {% url %} parameter
{% url django.views.i18n.set_language %} # quote or unquote based on your Django version

You don't care about the URL of the include, you care about the URLs inside the include. You should look at the code or the documentation for django.conf.urls.i18n to find the setlang URL you are interested in, and use that name.

Related

How to let user select currency in Django using Django-money?

I am currently working on an online store. I want a user to be able to change their currency option in the header and convert the whole site to the currency choice. I have found app called django-money, which seams to have that functionality, but I cannot find any implementation examples.
I want it to work like localize work in django. Having a form that will redirect to URL and saving choice in session and in cookie. This is the example of the language selection code.
/template.html
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}">
<select name="language" onchange="this.form.submit()">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.code|upper}}
</option>
{% endfor %}
</select>
</form>
And then whenever I need something to be translated I will use this inside html:
{% trans "Some text to translate" %}
So is there something similar for currency? What would be the action for the form? Please can somebody help if you have ready solution! I will really appreciate.

How to move singup\signin templates into dropdown menu?

I have a fixed navigation and I want to add dropdown box where users can singup\in (as Twitter uses).
I tried:
# project/tempates/signup.html
{% load i18n %}
{% load account socialaccount %}
{% block head_title %}{% trans "Signup" %}{% endblock %}
{% block content %}
<h1>{% trans "Sign Up" %}</h1>
<p>{% blocktrans %}Already have an account? Then please sign in.{% endblocktrans %}</p>
<form class="signup" id="signup_form" method="post" action="{% url 'account_signup' %}">
{% csrf_token %}
{{ signupform.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<button type="submit">{% trans "Sign Up" %} »</button>
</form>
{% endblock %}
# project/tempates/base.html
# ... a lot of basic stuff
<li class="dropdown">
<a class="dropdown-toggle" href="#" data-toggle="dropdown">Sign In <strong class="caret"></strong></a>
<div class="dropdown-menu" style="padding: 15px; padding-bottom: 0px;">
{% include './signup.html' %}
# ... rest stuff
and in dropdown box I see just the text, link to signin, and the button for confirmation of the registration.
There are no fields to enter email and passwords. As I understand, this is because no access to the form, what usually is a views' jobs. How can I get workable dropdown forms?
After 2 days of internet digging I want to summarize what I found.
There are few ways:
1. Use <form action='some address here'>. The easiest way.
To check default AllAuth forms we need to:
# ./manage.py shell
>>> import allauth.account.forms as forms
>>> f = forms.LoginForm()
>>> print(f)
Below is edited version of print(f) which is added directly to base.html
<form action="{% url 'account_login' %}" method="post">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.get_full_path }}" />
<input id="id_login" name="login" placeholder="Username or e-mail" type="text" required />
<input id="id_password" name="password" placeholder="Password" type="password" required />
<label for="id_remember">Remember Me:</label>
<input id="id_remember" name="remember" type="checkbox" />
<button type="submit">Login</button>
Forgot Password?
</form>
Method is based on the solution from ->here<-
2. Contex processor
a) Make folder your_project/your_app/context_processor. Put there 2 files - __init__.py and login_ctx.py
b) In login_ctx.py add:
from allauth.account.forms import LoginForm
def login_ctx_tag(request):
return {'loginctx': LoginForm()}
c) In project's SETTINGS add your_app.context_processors.login_ctx.login_form_ctx' inTEMPLATES` section. Something like:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'templates', 'allauth')],
'APP_DIRS': True,
'OPTIONS': {
'debug': DEBUG,
'context_processors': [
'your_app.context_processors.login_ctx.login_form_ctx', # <- put your processor here
'django.template.context_processors.debug',
# [...other processors...]
],
},
},
]
d) In your *.html where you need add the next:
{% if not user.is_authenticated %}
<form action="{% url 'account_login' %}" method="post">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.get_full_path }}" />
{{ loginctx }}
<button type="submit">Login</button>
</form>
{% else %}
{# display something else here... (username?) #}
{% endif %}
3. Template tag
a) Make folder your_project/your_app/templatetags. Put there 2 files - __init__.py and login_tag.py
b) In login_tag.py add:
from django import template
from allauth.account.forms import LoginForm
register = template.Library()
#register.inclusion_tag('profiles/true_login.html')
def login_form_tag(current_page=None):
return {'loginform': LoginForm(),
'redirect_to': current_page}
c) In your_project/your_app/templates/your_app/ make file login_form.html with content:
{% load account %}
{% if not user.is_authenticated %}
<form action="{% url 'account_login' %}" method="post">
{% csrf_token %}
<input type="hidden" name="next" value="{{ redirect_to }}" />
{{ loginform }}
<button type="submit">Login</button>
</form>
{% else %}
{# display something else here... (username?) #}
{% endif %}
d) In any *.html you need, add at the top {% load login_tag %} and in the needed place add {% login_form_tag request.get_full_path %}
The 2nd and 3rd methods show native AllAuth form. If you need to edit it somehow using {{form}}, ->here<- in the doc you can find some examples how to do that. Want to mention, that if in the doc is shown something like:
<div class="fieldWrapper">
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject }}
</div>
for our case form must be changed to loginctx or loginform
Also you can write your own form or inherit AllAuth and import it to context processor or templatetag as shown above.
Both methods are based on ->this solution<-
In all 3 methods redirect works as needed (return a user to the previous page, in case of success login, else redirect to original AllAuth template at site.com/account/login).
All written above can be implemented to SignUP.
Also I asked some people, how to show errors in case of wrong username\password instead of redirect to site.com/account/login, a proposition was to use AJAX, but currently this is out of my knowledge. Some base info about connection signin\up forms to default AllAuth views can be found ->here<-. If anyone could implement it, or find any tutorial, please post it here.

NoReverseMatch on django generated views

I'm trying to create the views for all the authentication process in Django, but I have an issue with the reverse url tag in the views.
I have :
urls.py
url('^v1/back/', include('django.contrib.auth.urls'))
login.html
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<form method="post" action=".">
{{ form.as_p }}
<input type="submit" value="{% trans 'Log in' %}" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
<p>{% trans "Forgot password" %}? {% trans "Reset it" %}!</p>
<p>{% trans "Not member" %}? {% trans "Register" %}!</p>
{% endblock %}
And when I access localhost:8000/v1/back/login/ i have:
NoReverseMatch at /v1/back/login/
Reverse for 'django.contrib.auth.views.auth_password_reset' with
arguments '()' and keyword arguments '{}' not found. 0 pattern(s)
tried: []
The thing is, as, you can see, i try putting the complete path, it still does not work.
When I try to access another view like password change, it redirects me to :
http://192.168.56.103:8000/accounts/login/?next=/v1/back/password_change/
Which obviously does not work, and when i access password reset :
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<form method="post" action=".">
{{ form.as_p }}
<input type="submit" value="{% trans 'Submit' %}" />
</form>
{% endblock %}
It has the django admin look and feel instead on my base.html.
I'm guessing there are lots of problem here, I'm trying to solve them one by one, but i don't know what i've done wrong on the url part.
Don't know if this is relevant, but a part of my application is served by Django Rest Framework, and i'm trying to put in place oAuth2.
The correct name for password reset is just password_reset, to reverse it use:
{% url 'password_reset' %}
To fix the login redirect, you have to adjust the LOGIN_URL in your settings.py
I suggest you remove the part regarding the template and post it as a separate question.

invalid block-tag when I implement i18n

I'm currently adding i18n in my website but there is something wrong.
When I use code from djangoproject
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language">
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}">{{ language.name_local }} ({{ language.code }})</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
I get this error
Invalid block tag: 'get_language_info_list'
I don't understand why get_language_info_list is unknown. Templates_context_processors is ok. HTML form is on my homepage.
Always make sure you load the tag library first before you requests any tags. To use get_language_info_list, you need to make sure {% load i18n %} is in your template.

Implementing a login in django

In my base.html I placed this:
{% if user.is_authenticated %}
you are logged in!
{% else %}
<h3>Login</h3>
<form action="/login/" method="post" accept-charset="utf-8">
<label for="username">Username</label><input type="text" name="username" value="" id="username" />
<label for="password">Password</label><input type="password" name="password" value="" id="password" />
<p><input type="submit" value="Login →"></p>
</form>
{% endif %}
In urls.py:
(r'^login/$', 'django.contrib.auth.views.login'),
(r'^logout/$', 'django.contrib.auth.views.logout'),
When I accessed /login I had to make a login.html file. I created templates/registration/login.html:
{% extends "base.html" %}
{% block content %}
{% if form.errors %}
<p>Your username/pass didnt match</p>
{% endif %}
{% endblock %}
I'm not seeing the username/pass, but I'm still seeing the meaning my user is not authenticated yet.
Btw, I don't have the CSRF middleware loaded. Did I miss a step or two?
One other thing, I accessed logout.html and it went into my django admin logout page. I tried making a templates/registration/logout.html but it didn't override that part. Hrm?
Are you passing the user variable to your template context? Either explicitly, or via a context processor?
Doh. Apparently my actual template had action="/login" but when I typed it in the example here it had an end slash, I re-added the end slash and that was it.