views:

346

answers:

2

In my application, I have models that have the Users model as a Foreign key, eg:

class Doctor(models.Model):    
username=models.ForeignKey(User, unique=True)
...

In the admin site, when adding a new Doctor, I have the option of adding a new User next to the username field. This is exactly what I want, but in the dialog that opens, it asks for a username and password for the new user; I would also like to be able to assign a group to this new user. What would be the best way of doing this ?

Thanks, lokharkey

+1  A: 

In your application, create an 'admin.py', where you actually register your own model to admin, add following code.

from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm

class MyUserCreationForm(UserCreationForm):
    """
    A form that overrides the UserCreationForm
    """
    class Meta:
        model = User
        fields = ("username", "groups")

UserAdmin.add_form = MyUserCreationForm

admin.site.register(Doctor)

Now you just need to override the template that render this overridden form. Create a directory structure as,

"your_project_root_directory"/templates/admin/auth/user/add_form.html

and copy the content as,

{% extends "admin/change_form.html" %}
{% load i18n %}

{% block after_field_sets %}

<p>{% trans "First, enter a username and password. Then, you'll be able to edit more user options." %}</p>

<fieldset class="module aligned">

<div class="form-row">
  {{ form.username.errors }}
  {# TODO: get required class on label_tag #}
  <label for="id_username" class="required">{% trans 'Username' %}:</label> {{ form.username }}
  <p class="help">{{ form.username.help_text }}</p>
</div>

<div class="form-row">
  {{ form.password1.errors }}
  {# TODO: get required class on label_tag #}
  <label for="id_password1" class="required">{% trans 'Password' %}:</label> {{ form.password1 }}
</div>

<div class="form-row">
  {{ form.password2.errors }}
  {# TODO: get required class on label_tag #}
  <label for="id_password2" class="required">{% trans 'Password (again)' %}:</label> {{ form.password2 }}
  <p class="help">{% trans 'Enter the same password as above, for verification.' %}</p>
</div>

<div class="form-row">
  {{ form.groups.errors }}
  {# TODO: get required class on label_tag #}
  <label for="id_groups" class="required">{% trans 'Groups' %}:</label> {{ form.groups }}
  <p class="help">{% trans 'All existing Groups listed here. If you are not seeing any group, means you dont have any groups object created.' %}</p>
</div>

<script type="text/javascript">document.getElementById("id_username").focus();</script>

</fieldset>
{% endblock %}

And you are good to go. Its working snippet.

simplyharsh
A: 

Just out of curiosity, is this type of solution considered kosher in Django? That is, it seems like copy/pasting a big chunk of code like this goes against the DRY principle that the Django developers promote.

Matt