I'm using django-registration. I'd like to update the AuthenticationForm in 'django.contrib.auth.forms'. Specifically, I would like to pass the 'attrs' dict to add a few attributes. How do I update a form that comes with django?
You can use the views that come with auth and override the form parameter with your own form:
django.contrib.auth.views.login(request[, template_name, redirect_field_name, authentication_form])
More info here.
The standard way is to subclass AuthenticationForm, change the attrs in constructor, pass the form to login view and write a new entry in urls.py.
This is a nightmare: in order to add html attribute to a field it is necessary to use python subclassing, to know how exactly django's form metaclass work (self.fields['field'].widget.attrs, not just self.field.widget.attrs), to know regexes (for urls.py), to know how django's urls.py work (should you put the overriding line before of after include('django.contrib.auth.urls')?) and to know where is the auth form and auth view imported from.
And now the "commercial break": just use http://pypi.python.org/pypi/django-widget-tweaks for your task ;)
Related
I have a django and I wrote some views. I know how to pass my variables to template, but I also has some external modules with their own views, which I wont modify. Please help me understand how can I get one of my object "Menu.objects.all()" exist in all templates? So for example a I have django-registration and i want to have all my menu items appear at top when someone visits not my app url. I mean it will be registration app url, which returns templateresponse (and here I dont have my variable).
You can add variables to context
The cleanest way to do it, is to use a Template Context Processor, which is a hook that will allow you to add things to your context before the template is rendered.
http://www.djangobook.com/en/2.0/chapter09.html
https://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-own-context-processors
Here's an example of Template Context Processors used in the django core:
https://github.com/django/django/blob/master/django/template/context_processors.py
Is it possible to do something like this in urls.py?
urls.py: http://pastebin.com/raw.php?i=QVQ8BEvJ
This is not right way to implement it.
The best solution is to wrap your views with #login_requered decorator.
Example:
#login_required
def home_page(request):
...
You can specify in your settings.py LOGIN_URL where user will be redirected if not authorized.
Please read more at django documentation
Authentication checks should be performed in the view, that's where checks and security are ment to exist.
Apart from that you can decorate Class Based Views in urls to check for login, but the most common / sensible / usual approach is to make that check in the view.
If you are using Class Based Views then you could create a Mixin which checks if the user is authenticated, this combined with the tools Django Offers, allow you to redirect the user to the appropriate view (login, or if check is passed allow him to view the requested url).
If you are using function based views, then Django offers decorators for those functions to provide common "needs" of a web framework.
PS If you are using CBV's then django-braces has already a few wonderful mixins available for common tasks (Ajax, Security etc).
So, I want to use a default Django admin form in a form wizard, because there are a number of objects with foreign keys to the main object on both the first and second pages of this form, and I'd like to be able to edit them inline. I used the example at http://elo80ka.wordpress.com/2009/10/28/using-a-formwizard-in-the-django-admin/ as a base, however, he specifies his own form that he has the admin use. Of course, if you use your own custom form, inlines won't work with that. So, I tried doing the following:
create_syllabus = SyllabusCreationWizard([SyllabusAdmin.form, CalendarForm])
If I do so, however, I get the following error:
'ModelForm' object has no attribute '_meta'
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/Charybdis/syllabus/add/
Django Version: 1.4
Exception Type: AttributeError
Exception Value:
'ModelForm' object has no attribute '_meta'
Exception Location: C:\Python27\lib\site-packages\django\forms\models.py in __init__, line 229
Python Executable: C:\Python27\python.exe
It would appear that the auto generated Admin form does not specify the class Meta information that a regular ModelForm is required to.
My question, then, is if there's any way to use the default admin form with the FormWizard. Do I need to somehow supply the Meta for the admin form, and if so how? Or do I need to be doing something else entirely?
I guess it's a problem with how the form is created and used in the ModelAdmin.
If you call 'SyllabusAdmin.form' it will be the class ModelForm, uninitialized.
Afaik ModelAdmin uses get_form to actually create and configure the form.
In your case you would have to do something like
form = SyllabusAdmin(SyllabusModel, admin.site).get_form(request)
to achieve what you want... hope it answers your question.
The built-in actions that come with the Django admin generally display a helpful message after they execute at the top, e.g. saying that a new object was added or what have you.
The docs show how to do it with simple actions that can be represented as methods of the custom ModelAdmin. However, with custom actions that need intermediate pages (covered further down on that same page), I am encouraged to pass the user onto another view. That's great, but it means that I no longer have access to the custom ModelAdmin instance in order to call its message_user() method... Or at least I'm not sure how to get it.
Can you tell me how to get a hold of the current ModelAdmin instance or, if there's a better way, how else to display one of those helpful little messages when I'm done in the other view?
To mimic the ModelAdmin.message_user method you only need to do the following:
from django.contrib import messages
messages.info(request, message)
Adding a message is documented here https://docs.djangoproject.com/en/dev/ref/contrib/messages/#adding-a-message and the way ModelAdmin uses it can be seen here: https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L691
Construct a LogEntry and write a custom templatetag to render messages on your intermediat page, for instance:
LogEntry.objects.log_action(
user_id=request.user.id,
content_type_id=ContentType.objects.get_for_model(yourmodel).pk,
object_id=case.id,
object_repr=force_unicode(yourmodel),
action_flag=ADDITION if created else CHANGE)
read more: Django docs (Message Framework)
I need to override the an add form within the admin panel.
I'm thinking of accomplishing this by writing a view which would then point to the admin view for the final result.
Something similar to this (where admin_basic_ass_user_view is the admin view)
#required_login
def add_user(request):
if condition:
return admin_basic_add_user_view(request)
return render_to_response("admin/auth/user/add_form.html", { ... })
Any ideas?
Why not just override the relevant methods with your ModelAdmin subclass? That's why it's a class, after all.
Add something like this to your urls.py
((r'^admin/auth/users/add/$', 'Project.SomeAPP.admin_views.add_user'),
The path needs to point to your new view. You should see the results of your new view in the admin interface's add user page.
EDIT: I forgot to mention, make sure you add that line BEFORE the normal admin interface line in the urls.py