Django django-custom-user and registration becomes no-op - django

Registration fails silently with django-custom-user
I'm switching from using the default registration model to a custom model (to drop username and just authenticate with email address). An existing user can login, but creating a new user fails silently now. I call url 'registration_register', I get the user create form I expect, I fill it in and click the submit button, and...the form redisplays with email but not password, no error, no user creation.
registration_form.html
{% extends "..." %}
{% block content %}
<form method="post" action="{% url 'registration_register' %}">
{% csrf_token %}
{{ form.email.errors }}
<label for="{{ form.email.id_for_label }}">mail</label> {{ form.email }}
<br>
{{ form.password1.errors }}
<label for="{{ form.password1.id_for_label }}">password</label> {{ form.password1 }}
<br>
{{ form.password2.errors }}
<label for="{{ form.password2.id_for_label }}">password</label> {{ form.password2 }}
<br>
<input type="submit" value="Create" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
More background
I pip install django-custom-user and make the changes recommended here -- adding to INSTALLED_APPS, db sync (in fact, it's a new project, so db delete and create), and the couple code changes to use it. I've left 'registration' in INSTALLED_APPS.
Django (1.7.6)
django-custom-user (0.5)
My urls.py still points to registration.backends.default.urls.
url(r'^accounts/', include('registration.backends.default.urls')),

Well the problem you face is that django-registration expects a username as well as a password and an email address. As you can see in the source code of django-registration
https://bitbucket.org/ubernostrum/django-registration/src/8f242e35ef7c004e035e54b4bb093c32bf77c29f/registration/backends/default/views.py?at=default#cl-74
If I were you I would simply create a simple form and use a FormView from django. After, in order to match django-registration you could do more research and try to fit django-registration with django-custom-user.
It could be that you create a class that inherits django-custom-user, or that you change the form or anything like that. Otherwise you could even fork django-registration and update it according to django-custom-user and then use it for your project and make it available on github as django-registration-custom-user

Have you tried python manage.py makemigrations and python manage.py migrate?
Also try displaying the form as form.as_p in order to get all fields and all errors displayed automatically. Forget about CSS for now.
Also what package is registration.backends.default.urls ?
Because it is not django-custom-user
I hope this helps

Related

Trouble with Django Logout Page, django-registration logout.html Template Form Fields

I am using django-registration. After getting it working, I went on extending views and forms for field customization using Bootstrap.
I have this working for everything except the logout page. In the default method, I simply built the form by scratch and it worked OK. But when trying to use Django's forms, it's not showing the fields at all. Both the login and logout templates use this basic form:
<div class="auth-form">
<form class="form-signin" method="post" action="/accounts/login/">
{% csrf_token %}
<h2 class="form-signin-heading">Please log in</h2>
<div class="font-16px top-mar-1em">
<label for="id_username"></label>
{{ form.username }}
<label for="id_password1"></label>
{{ form.password }}
<div class="form-group">
<div class="col-sm-10">
<div class="level-checkbox">
<label for="checkbox">
{{ form.remember_me }} Remember me
</label>
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Log in</button>
</div>
</form>
</div>
This works fine for the login page, but for the logout page it doesn't (the fields are missing). It's like the form is not available to this page. I'm sure I missed something simple but I can't figure it out.
My urls.py section look like this:
url(r'^accounts/login/$','django.contrib.auth.views.login', {
'template_name': 'registration/login.html',
'authentication_form': UserAuthenticationForm,
}),
I've tried adding a logout section to urls.py similar to the login one, but that hasn't worked. I've tried using logout_then_login, using login.html as import template on logout.html and other miscellaneous things to no avail.
Apparently, there is no form associated with the default logout view, so this is probably the issue but I'm not sure the best way to implement a standard form in the logout view.
You should be able to add the following to your urls.py and have everything work.
url(r'^accounts/logout/$','django.contrib.auth.views.logout_then_login')
Make sure you have LOGIN_URL defined your settings.py. Then when a user clicks a logout link they will hit the logout view which takes care of redirecting to the login view which contains your form.
Thanks to #tsurantino I was able to get this working using the messages framework. I always like when I have to implement a new feature using a part of Django I haven't used before. Adding to the toolkit, so to speak. Here is what I did:
Since I had a signal_connectors.py file already for sending email based on user registration/activation I just added to it:
#receiver(user_logged_out)
def user_logged_out_message(sender, request, **kwargs):
messages.add_message(
request,
messages.INFO,
'You\'ve been successfully logged out. You can log in again below.'
)
Then in my common app's __init__.py I imported it:
from common.signal_connectors import user_logged_out_message
Then in my login.html template:
{% if messages %}
<div class="alert-success align-ctr font-16px top-mar-2em">
{% for message in messages %}
{{ message }}
{% endfor %}
</div>
{% endif %}
Finally, to redirect to login page after logout (urls.py):
url(r'^accounts/logout/$','django.contrib.auth.views.logout_then_login'),
Thanks for everyone’s help and comments.

ImproperlyConfigured at /login/ Error importing authentication backend backends.EmailAuthBackend: "No module named backends"

i'm working on Django project, i searched for a while how login and t found that the easiest way is to "django.contrib.auth". so i added my login view to urls.py :
url(r'^login/$','django.contrib.auth.views.login',{'template_name': 'login.html'}),
and this is my template :
<html>
<head>
<title>Django Bookmarks - User Login</title>
</head>
<h1>User Login</h1>
{% if form.errors %}
<p>Your username and password didn't match.
Please try again.</p>
{% endif %}
<form method="post" action=".">{% csrf_token %}
<p><label for="id_username">Username:</label>
{{ form.username }}</p>
<p><label for="id_password">Password:</label>
{{ form.password }}</p>
<input type="hidden" name="next" value="/" />
<input type="submit" value="login" />
</form>
</body>
</html>
It seems you have added some custom backend in settings.py
Try this on shell:
from django.conf import settings
settings.AUTHENTICATION_BACKENDS
Seems django is trying to import a module named backends which you do not have because of some path mistake you are making.
If EmailAuthBackend is defined in a module named backends.py in an app some_app, you need to add some_app.backends.EmailAuthBackend to AUTHENTICATION_BACKENDS.
In early Django versions, this can be due to some backends.py.
I wanted to create an activation email and I used AUTHENTICATION_BACKENDS = ['authentication.backends.EmailBackend'] in my settings.py then I created a file named backends.py, afterward, I deleted backeds.py (because you won't need that in early Dj versions, at least for email verification) and I forgot to delete the AUTHENTICATION_BACKENDS = ['authentication.backends.EmailBackend'] from my settings.py, and that caused the error.

Django URL is being changed by a submit button

I'm very new to Django and not super familiar with web programming in general, so it's very likely that there is an easy fix to my problem that I'm just unaware of.
My web app is a photo gallery. People can click on a photo to see an enlarged version with buttons on either side for older or newer pictures. In addition, the photos in the gallery can be sorted by tags, which are passed along as URL parameters.
My problem is that when I click on one of the submit buttons, Django replaces the parameters in my URL with the name of the button, thus destroying my reference to what tag I was using. For example, "127.0.0.1:8000/gallery/view/6/?tag=people" upon clicking next, gets converted to "127.0.0.1:8000/gallery/view/6/?older=Older" when it's trying to process the URL.
Code from my HTML:
<form action="/gallery/view/{{ photo.id }}/?tag={{ tag }}" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
In my view.py I pass in the tag plus other information in a render_to_response, but I'm not sure how to/if I can reclaim it while handling the buttons.
render_to_response('item/view.html', {'photo':photo, 'tag':tag, 'related_tags': related_tags, 'related_photos': related_photos, 'has_newer': has_newer, 'has_older': has_older}, context_instance=RequestContext(request))
Here's the view.py code for processing the buttons:
if 'newer' in request.GET:
if has_newer:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(newer[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
if 'older' in request.GET:
if has_older:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(older[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
<form action="/gallery/view/{{ photo.id }}/" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<!--This will append a tag parameter with given value to the querystring -->
<input type="hidden" name="tag" value="{{ tag }}">
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
Note that the query string is removed from action (as it won't be used) and the older and newer parameters will still be sent along.

How to use django.views.i18n.set_language() function?

I read a tutorial in Django site but I don't understand how to use the set_language() function. For example, I have a demo follow as:
index.html
{% trans "Hello World." %}
<form action="/i18n/setlang/" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="/next/page/" />
<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>
urls.py
urlpatterns = patterns('',
(r'^i18n/', include('django.conf.urls.i18n')),
)
views.py
What need I write to display the languages, which were chosen from user in this file?
Thanks,
Thinh
With the code you are using, you don't need to write your own views. The form will make a POST request to /i18n/setlang/, with the language code and (optional) the redirect-to (next) page as parameters.
The django view does the following (from the django documentation)
Django looks for a next parameter in the POST data.
- If that doesn't exist, or is empty, Django tries the URL in the Referrer header.
- If that's empty -- say, if a user's browser suppresses that header -- then the user will be - redirected to / (the site root) as a fallback.
So in essence, the user will be redirected after submitting the form, and the django view will set the language for that user according to what was submitted.
Hope this helps,
Hoff

Customizing django-comments

So, I'm using django.contrib.comments. I've installed it OK but rather than the unwieldy default comment form, I'd like to use a custom form template that just shows a textarea and submit button.
The rationale behind this is that user only see the form if they area already authenticated, and I'd like the keep the form simple and pick up their username etc automatically.
I've implemented a custom form, but am getting an error when I try to submit it.
Here's what I have in my template for the page with the comment form (entry is the object passed from the view):
{% load comments %}
{% render_comment_form for entry %}
And here's my HTML in /templates/comments/form.html:
{% if user.is_authenticated %}
<p>Submit a comment:</p>
<form action="/comments/post/" method="post">
<textarea name="comment" id="id_comment" rows="2" style="width: 90%;"></textarea>
<input type="hidden" name="options" value="{{ options }}" />
<input type="hidden" name="target" value="{{ target }}" />
<input type="hidden" name="gonzo" value="{{ hash }}" />
<input type="hidden" name="next" value="{{ entry.get_absolute_url }}" />
<span style="float:right;"><input type="submit" name="post" value="Add"></span>
</form>
{% else %}
<p>Please log in to post a comment.</p>
{% endif %}
It renders okay initially, but when I try to submit the comment form, I get the following Django error:
Comment post not allowed (400)
Why: Missing content_type or object_pk field.
Can anyone help?
The comment model uses a generic foreign key to map to the object for which the comment was made such as a blog entry. These are required hidden fields included in the standard comment form.
From django.contrib.comments.models
...
class CommentSecurityForm(forms.Form):
"""
Handles the security aspects (anti-spoofing) for comment forms.
"""
content_type = forms.CharField(widget=forms.HiddenInput)
object_pk = forms.CharField(widget=forms.HiddenInput)
...
If you haven't changed the form class and only want to change the html template then you can include these fields by adding a for loop over all the hidden fields.
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
Fixed the problem by copying from Theju's app - in particular, see Joshua Works' comment on part 2.