Hi all,
Is there some way of creating a single form that combines multiple
Models (Auth, User and AuthPermissions as seen in my example below)
and treats them as a single object (not a relation of multiple
objects)?
I tried to do this myself using the code below. When I use it the
user.save() will raise a DB Integrity error if I enter an already used
username in the form. I thought the DJango ModelForm validation should
take care of this when calling form.is_valid().
What I am trying to do is have a single form that "merges" all the
information for the relevant models instead of having the user see
relations between the models.
Internally in our system the User and Auth records must be separate as
we have other methods of authenticating not just using a username/
password from a User record. This also means I have not found a way of
using the standard DJango authentication system. But it would be good
to leave that for another thread.
I am currently using DJango 1.2.1
Thanks,
Brendon.
#----------------------------
# Models
#----------------------------
class Permission(models.Model):
name = models.CharField(max_length=128, primary_key=True,
choices=PERM_DESCRIPTIONS.items())
class Auth(models.Model):
id = models.AutoField(primary_key=True)
developer = models.ForeignKey(Developer, null=True)
application = models.ForeignKey(Application, null=True)
permissions = models.ManyToManyField('Permission',
db_table='AuthPermissions')
class User(models.Model):
id = models.AutoField(primary_key=True)
auth = models.OneToOneField(Auth)
username = models.CharField(max_length=128, unique=True)
pwhash = models.CharField(max_length=128)
#----------------------------
# Custom Form
#----------------------------
class UserForm(django.forms.ModelForm):
scope = django.forms.ChoiceField()
password = django.forms.CharField(max_length=128,
widget=forms.PasswordInput())
password_confirm = django.forms.CharField(max_length=128,
widget=forms.PasswordInput())
permissions =
django.forms.MultipleChoiceField(choices=models.PERM_DESCRIPTIONS.items(),
required=False)
class Meta:
model = core.User
fields = (
'scope',
'username',
'password',
'password_confirm',
'permissions')
def clean(self):
cd = self.cleaned_data
if cd.get('password') != cd.get('password_confirm'):
raise forms.ValidationError(u'Password confirmation
didnt match')
return cd
def SetScopeChoices(self, request, choices):
if request.method != 'GET':
self.fields['scope'].choices = choices
if len(choices) == 1:
self.fields['scope'].widget =
django.forms.widgets.HiddenInput()
self.fields['scope'].initial = choices[0][0]
else:
self.fields['scope'].widget.choices = choices
self.fields['scope'].initial = choices[0][0]
#----------------------------
# View
#----------------------------
@require_login
def HTMLUserCreate(request):
# Calculate the choices available for creating a new users scope
choices = wutils.GetScopeChoiceList(request.dan_auth)
if request.method == 'GET':
form = UserForm()
form.SetScopeChoices(request, choices)
elif request.method == 'POST':
form = UserForm(data=request.POST)
form.SetScopeChoices(request, choices)
if form.is_valid():
# Obtain the users form data
cd = form.cleaned_data
(developer_id, application_id) =
ScopeIDStrToDevApp(cd['scope'])
# Create the auth object
auth = core.Auth(
developer_id=developer_id,
application_id=application_id)
auth.save(force_insert=True)
# Add permissions to the auth
auth.permissions=cd['permissions']
auth.save()
# Create the user object for the new auth object
user = core.User(
id=auth.id,
auth=auth,
username=cd['username'],
pwhash=HashPassword(cd['password'])
)
user.save(force_insert=True)
return HttpResponseRedirect('/user/'+str(user.id)+'/')
return render_to_response('user_create.html', {'form': form},
context_instance=RequestContext(request))
--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en.