Re: How to require selection of a M2M with intermediate table/model during admin record creation?

2013-08-31 Thread M Hill
Another application of the validation occurred to me:  Since multiple rows 
can be added to the form, I would want to check for and reject multiple 
selections of the same Position title.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
For more options, visit https://groups.google.com/groups/opt_out.


How to require selection of a M2M with intermediate table/model during admin record creation?

2013-08-28 Thread M Hill


I have been beating my head against the wall trying to figure this out.  I 
came up with a simplified example to illustrate what I'm trying to do.

Posit a hypothetical university application; say, a system where students, 
faculty and administration can all participate.  There are different 
privilege levels and different areas of functionality, so students will 
never see the screens that professors use for tracking assignments, etc.  
The various permissions will be designated by somebody's Position, which 
includes student (undergrad), student (graduate), TA, professor, and dean.  
(This is a contrived example, to try to illustrate what I'm trying to 
accomplish.)  As you can see, a User can have multiple Positions:  grad 
student and TA, or professor and dean.  The areas of functionality are also 
accessible by overlapping Positions, with the Position determining how much 
they can do in that screen.  As I said, students will not even know of the 
assignment tracking screen, but TAs and professors will, and professors 
will be able to do more in it.  Professors will not see the administration 
functions, unless they are also a dean.

I plan to have a single User and login per person.  Users with multiple 
Positions will be prompted which one to use per session.  Here is the 
models.py:

from django.db import models

# Create your models here.
class Position (models.Model):
  CHOICES = ( ('pub', 'Publish'), ('die', 'Perish') )
  title = models.CharField (max_length=32)
  privileges = models.CharField (max_length=3, choices=CHOICES)

class User (models.Model):
  login = models.EmailField (unique=True)
  name = models.CharField (max_length=32)
  password = models.CharField (max_length=32)
  positions = models.ManyToManyField (Position, through='UserPosition')

  def __str__ (self): return self.name

class UserPosition (models.Model):
  user = models.ForeignKey (User)
  position = models.ForeignKey (Position)
  effectDate = models.DateField()

So there's an intermediate model for the M2M relationship so I can store 
extra information per User/Position.

Here's the stock admin.py:

from django import forms
from django.contrib import admin
from forum.models import *

admin.site.register (User)
admin.site.register (Position)

This is the view.  As you can see, it doesn't accommodate hooking up the 
new User with any Position(s).


So I wrote a UserAdmin and a form to go with it.  The new admin.py:

# imports

class UserPositionAdmin (admin.TabularInline):
  model = UserPosition
  extra = 1

class UserCreationForm (forms.ModelForm):
  
  class Meta:
model = User

class UserAdmin (admin.ModelAdmin):

  form = UserCreationForm
  inlines = (UserPositionAdmin,)

admin.site.register (User, UserAdmin)
admin.site.register (Position)

Now the input form looks like this:


Now my problem is that I require each User to have at least one Position, 
but I can't figure out how to get the form to fail validation (i.e., in the 
clean() call) if no Position is selected in the inline.  I've tried waiting 
until the User's save() function is reached, and tried checking in the 
UserAdmin's save_model(), but so far have been unable to find out at those 
points if a Position was selected before form submission or not.  So I 
think the UserCreationForm is the right place to check for it.

The problem seems to be that the field isn't technically part of the User 
class, so the form validation doesn't look for a clean_userpositions() 
function.  I tried creating a function by that name, but it never got 
called if the Position was blank (I didn't test with a valid Position 
selection).

It seems to me this can't possibly be something nobody's ever done before, 
but I haven't been able to find the answers even in the voluminous Django 
1.5 documentation.  I would greatly appreciate direction on how to validate 
that a Position is selected.

Thanks in advance.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Inheritance question: Multiple roles for users

2013-04-18 Thread M Hill

>
> Model inheritance is not the same as object inheritance. 
>
> If you are doing non abstract inheritance, then there is no difference 
> between a derived model, and a model that has a foreign key to the 
> parent class. In a derived model, the foreign key is a OneToOneField, 
> with null=False, blank=True. In other words, inheritance is exactly 
> the same as composition for non abstract inheritance. The main 
> difference is that if you inherit, the fields that are actually in the 
> parent table magically appear as attributes of your derived object and 
> all your queries involving this table require a join. Magic is bad, 
> extra joins are bad, magic that causes extra joins are double bad. 
>

Tom, Many thanks for the detailed reply. 

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




Inheritance question: Multiple roles for users

2013-04-18 Thread M Hill
I've searched this group for threads related to multitable inheritance.  
The one most similar to my query so far was titled "multiple children in 
multitable inheritance", from Apr. 2008.  Like the original poster, I'd 
thought of Bar as a possible subclass of Place, which might share the same 
Place parent/base class as a Restaurant.  However, that analogy doesn't 
quite capture what I'm trying to do, so I'll use another.

Say I am managing a martial arts tournament, where Members participate.  I 
would use Member as the base class that would hold all the details common 
to each person, which would include the login name.

Some Members are qualified to be Judges, Timekeepers, Referees, etc.  So 
those people can assume multiple roles at a tournament, but only one such 
role at a time.

The main reason I'd like to subclass Member is so that person-specific 
*and*role-specific information can be displayed depending on the Member's 
current role.  I saw Malcolm Tredinnick's comment to the effect that the 
answer to using inheritance is usually "no".  However, if I think about 
using Many-to-Many relations to track the Member's available roles, I run 
into the problem that not every Member will be a Judge, so I can't just 
have a "Member.roles -> intermediateTable <- subclass" field.

Furthermore, I need to delegate to another class of Member (TourneyAdmin?) 
the ability to add/manage/remove Members and their roles, and it would be 
very convenient if the admin interface could be used for that purpose.  
However, I can write my own management screens if that turns out to be 
necessary.

I would be very grateful for suggestions on how best to handle this type of 
use case.  I'm sure it's been solved (many times) before, but it seems 
quite difficult to come up with just the right search terms to zero in on 
the right threads without a bunch of false positives.

Thank you.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.