Using django-registration forms in custom templates - django

I'm trying to create an account settings page for logged-in users. One of the things users should be able to do is to change their password.
I'm using django-registration and it provides a password change form at site/accounts/password/change by default, and it works. However, I want this function to be available at an Account Settings page instead, along with other administrative functions.
I first tried copying the template code, but it did not work because it includes a special form to create the inputs for the passwords (to handle validation). I don't know how to include this form in my own template.
How can I recreate these forms in my own Account Settings template?
This is the default password change template. I want to reuse form.oldpassword and the others in a separate template.

Django-registration doesn't implement its own password change view, it reuses the one included in Django (django.contrib.auth.views.password_change). It is hooked in through registration.auth_urls which is included in the default and simple registration backends.
By default the view uses django.contrib.auth.forms.PasswordChangeForm (which can be overridden through the password_change_form parameter).
When you only reuse the form (which you can do of course, just import the above form in your custom view), you should be aware that you would still be missing the whole view logic. So unless you have a more complex view in mind, you should consider to reuse it and just override the registration/password_change_form.html and registration/password_change_done.html templates.

Related

Wagtail PASSWORD_REQUIRED_TEMPLATE is not overriding the default login

I'm building a global login page for Wagtail. The setting for PASSWORD_REQUIRED_TEMPLATE isn't working. In fact, i can't find n example where it actually does work which makes me think that I don't understand what it's supposed to do.
When I add; PASSWORD_REQUIRED_TEMPLATE = 'utils/auth/password-required.html' to the settings file it does not catch the login form and use my custom form.
Is this a know issue?
I think you've misunderstood what this is for. The PASSWORD_REQUIRED_TEMPLATE is used when someone tries to access a page that has been marked as private, and requires a password to view.
This is independent of whether or not the user is logged in, and is a different form entirely from the regular login form, which appears to be what you're trying to override.
If you want to change the frontend login form, then you need to set WAGTAIL_FRONTEND_LOGIN_TEMPLATE.
If you want to change the admin login form you need to override the wagtailadmin/login.html template.

Interface to allow users to edit their Django model entries

The admin interface for editing (adding, deleting, changing) entries in the database is great. I am working on a system, based on HTML forms, to allow users to edit information relevant to them in the database. This will take a lot of work, and look less than professional. Is there a standard way to allow a logged in user to use an administration-interface-like page to edit their (and only their) entries in a DB/model?
You can probably do what you need by customizing django admin. In django admin you can define get_queryset method to restrict objects available for current user. See https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_queryset, example there matches pretty well to your task
One use case for overriding this method is to show objects owned by the logged-in user...

Redirect a custom form to django admin form

I created a custom admin form for a particular model. All functionalities working. Now I want to call this form from the click of a button on another page that I have created. I was able to do that by creating an object of the form class, but it doesn't render the form as the admin site does (I had some fieldsets etc defined). Can I straight away redirect to the admin site's form? That would avoid duplicating the code for how I handle the form data. Any other leads would also be appreciated.
Now I want to call this form from the click of a button on another page that I have created.
Is this also within the admin interface? If so, don't use the admin view for all your users. As that will require nasty stuff with groups, permissions, etc.
I was able to do that by creating an object of the form class, but it doesn't render the form as the admin site does (I had some fieldsets etc defined).
Isn't this as expected, as the admin site comes with its own css and javascript? So you need to write it yourself
Can I straight away redirect to the admin site's form? That would avoid
duplicating the code for how I handle the form data. Any other leads
would also be appreciated.
True, but I believe the admin views have special authorisation checks on them. So you come back to the things with groups and permissions.
What I would do is move your form handling to an method in like utils.py and call this method from the normal and admin view.

replace Add with Get on django admin site

I have a model that I don't want user to manually add/delete objects. Instead, I want to have some Get button that once clicked, it executes some code and automatically update the database.
I was able to do similar things via adding my own admin action. However, adding an admin action by default means you have to have at least one object for your model, you select that object and performs some action.
I want be able to perform my customized action on an empty model (if I can replace the Add button with a Get button on the index page, it will be perfect). Is there a way to do so? thanks!
You could override the add_view method of the django admin model and do whatever you felt like having that view do if you wanted. Poke around through the ModelAdmin code and you can see what it does by default
you could also take a look at this project: https://github.com/imtapps/django-admin-ext and see an example of how to register your own urls for an admin... so you could make your view something like admin/myproject/myapp/model/get and have it do what you'd like...
You can prevent users from adding new objects by removing the "Can add ModelName" permission from that user. If they're a superuser that won't actually stop them from doing that, however.
Admin actions are designed to be run on specific instances of the model; if that's not what your code is doing you probably shouldn't go that particular route. You can override the admin template for your model and add a new button or link to your custom view. You could also remove the Add button entirely by eliminating it from your template, but I'd recommend using permissions instead.

django-registration view customization

I'm using django-registration (see: https://bitbucket.org/ubernostrum/django-registration ) on one of my projects. The standard setup for the django-registration is to add a the code below in the urls.py file
(r'^accounts/', include('registration.urls'))
and also customize the templates in a folder called registration.
The code above is creating links to the registration, login and password recovery which is fine. But in my project there are some other functions I usually add to my views so if I just add the include('registration.urls') it appears that I have no way of customizing the views containing those django-registration forms.
Is there a way to call the forms used by the django-registrationin a view so I can add a few more things on those views ?
The registration form is provided by the registration backend. Check out registration.backends.default.DefaultBackend.
There's a method get_form_class(request) that returns the registration.forms.RegistrationForm class. All you have to do is create a new backend, inherit from DefaultBackend and override the get_form_class() method to return a new form class.
You can pretty much do anything by providing a custom backend, except changing the base behavior of the registration app. If you need to radically customize the views in a manner that providing a custm backend doesn't make the cut, then just create a authn or users app and import any bits from django-registration you find useful. You can, say, keep the default models and managers within the registration app namespace, but hook up a custom backend to your own internals in a new app.