Validation on a Many-to-Many Through model ( unique_together=[a, b, c=1] )

2010-09-27 Thread Heleen
I have the following models (simplified example):

class Book(models.Model):
 users = models.ManyToManyField(User, through=Permission)

class Permission(models.Model):
 user = models.ForeignKey(User)
 role = models.ForeignKey(Group)
 active = models.BooleanField()
 book = models.ForeignKey(Book)

What I need is that for a Book instance there cannot be more than one
User of with the same Role and Active. So this is allowed:

Alice, Admin, False (not active), BookA
Dick, Admin, True (active), BookA
Chris, Editor, False (not active), BookA
Matt, Editor, False (not active), BookA

But this is not allowed:

Alice, Admin, True (active), BookA
Dick, Admin, True (active), BookA

Now this cannot be done using unique_together, because it only counts
when active is True. I've tried to write a custom clean/
validate_unique method (like how I have done here:
http://stackoverflow.com/questions/3052427/validation-on-manytomanyfield-before-save-in-models-py/3266169#3266169).
But it seems that when you save a Book and it runs the validation on
each Permission, the already validated Permission instances aren't
saved until they've all been validated. This makes sense, because you
don't want them to be saved in case something doesn't validate.

Could anyone tell me if there is a way to perform the validation
described above?

P.S. I could imagine using the savepoint feature (http://
docs.djangoproject.com/en/1.2/topics/db/transactions/), but I only
really want to consider that as a last resort.

Note! I first posted this question on StackOverflow. I received a
response but the answer wouldn't work for me. Please have a look at
the response to avoid repeating the answer: 
http://stackoverflow.com/questions/3759687/

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



Re: Admin Model Validation on ManyToMany Field

2010-07-15 Thread Heleen
Thanks very much for your reply!
I got it working now. At first I couldn't get my head around how it
would work using the clean of the intermediary model. But after a
night's sleep it made sense to me.
In the Admin my Permission model (the users field) is an inline of
Application and when I put the validation on Permission it also
automatically works in the Application Admin.

So now I have:

admin.py
class PermissionInline(admin.TabularInline):
form = PermissionForm
model = Permission
extra = 3

forms.py
class PermissionForm(forms.ModelForm):
class Meta:
model = Permission

def clean(self):
cleaned_data = self.cleaned_data
user = cleaned_data['user']
role = cleaned_data['role']
if role.id != 1:
folder = cleaned_data['application'].folder
if len(filter(lambda x:x in
user.profile.company.all(),folder.company.all())) > 0: # this is an
intersection
raise forms.ValidationError("One of the users of this
Application works for one of the Repository's organisations!")
return cleaned_data

And this works!

On Jul 14, 5:16 pm, jaymzcd <jaym...@googlemail.com> wrote:
> Hi Heleen,
>
> I think this is because your running the users through an intermediate
> model. That changes the way you need to work with the M2M data. You
> should be working on the Permission model/objects instead. If you
> check out the M2M docs for models via an intermediate:
>
> http://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-o...
>
> You'll see the example is pretty much what you have only with Group
> instead of Application.
>
> "The only way to create this type of relationship is to create
> instances of the intermediate model. Unlike normal many-to-many
> fields, you can't use add, create, or assignment (i.e.,
> beatles.members = [...]) to create relationships:"
>
> jaymz
>
> On Jul 14, 2:32 pm, Heleen <heleen...@gmail.com> wrote:
>
> > Thank you for your reply.
>
> > Yes I have selected a user and folder.
> > I believe ManyToMany fields are always optional (hence many to many).
> > So my users and company fields are optional, but my folder field
> > isn't.
> > When I add a new Application in the Admin I do specify a folder and
> > users (if I don't I would at least get a 'Required field' error for
> > the folder field).
> > I've tested the method above (clean function) with another model that
> > has a manytomany field, and it does exactly the same thing, even when
> > I really do fill in the data. In fact, if I delibirately throw an
> > error and look in the debug info I can see the ManyToMany field data
> > being present in the POST data, just like I can when I do the same
> > thing with the above models.
>
> > Btw, I just noticed a typo in my Folder model description above,
> > that's not the issue as it's correct in my original model.
>
> > On Jul 14, 2:02 pm, Nuno Maltez <nuno.li...@gmail.com> wrote:
>
> > > Hi,
>
> > > Just a guess: have you actually selected a user and a folder when
> > > submitting the form? I think only valid field are present on the
> > > cleaned_data dict, and your users and folder fields are not optional
> > > (blank=True, null=True).
>
> > > hth,
> > > nuno
>
> > > On Tue, Jul 13, 2010 at 1:45 PM, Heleen <heleen...@gmail.com> wrote:
> > > > Hello,
>
> > > > I have the following classes:
> > > > class Application(models.Model):
> > > >  users = models.ManyToManyField(User, through='Permission')
> > > >  folder = models.ForeignKey(Folder)
>
> > > > class Folder(models.Model):
> > > >  company = models.ManyToManyField(Compnay)
>
> > > > class UserProfile(models.Model):
> > > >  user = models.OneToOneField(User, related_name='profile')
> > > >  company = models.ManyToManyField(Company)
>
> > > > Now when I save application, I would like to check if the users do not
> > > > belong to the application's folder's companies.
> > > > I have posed this question before and someone came up with the
> > > > following sollution:
> > > > forms.py:
> > > > class ApplicationForm(ModelForm):
> > > >    class Meta:
> > > >        model = Application
>
> > > >    def clean(self):
> > > >        cleaned_data = self.cleaned_data
> > > >        users = cleaned_data['users']
> > > >        folder = cleaned_data['folder']
> > > >        if
> > > > users.filter(profile__company__in=folder.company.all()).count() 

Re: Admin Model Validation on ManyToMany Field

2010-07-14 Thread Heleen
Thank you for your reply.

Yes I have selected a user and folder.
I believe ManyToMany fields are always optional (hence many to many).
So my users and company fields are optional, but my folder field
isn't.
When I add a new Application in the Admin I do specify a folder and
users (if I don't I would at least get a 'Required field' error for
the folder field).
I've tested the method above (clean function) with another model that
has a manytomany field, and it does exactly the same thing, even when
I really do fill in the data. In fact, if I delibirately throw an
error and look in the debug info I can see the ManyToMany field data
being present in the POST data, just like I can when I do the same
thing with the above models.

Btw, I just noticed a typo in my Folder model description above,
that's not the issue as it's correct in my original model.

On Jul 14, 2:02 pm, Nuno Maltez <nuno.li...@gmail.com> wrote:
> Hi,
>
> Just a guess: have you actually selected a user and a folder when
> submitting the form? I think only valid field are present on the
> cleaned_data dict, and your users and folder fields are not optional
> (blank=True, null=True).
>
> hth,
> nuno
>
> On Tue, Jul 13, 2010 at 1:45 PM, Heleen <heleen...@gmail.com> wrote:
> > Hello,
>
> > I have the following classes:
> > class Application(models.Model):
> >  users = models.ManyToManyField(User, through='Permission')
> >  folder = models.ForeignKey(Folder)
>
> > class Folder(models.Model):
> >  company = models.ManyToManyField(Compnay)
>
> > class UserProfile(models.Model):
> >  user = models.OneToOneField(User, related_name='profile')
> >  company = models.ManyToManyField(Company)
>
> > Now when I save application, I would like to check if the users do not
> > belong to the application's folder's companies.
> > I have posed this question before and someone came up with the
> > following sollution:
> > forms.py:
> > class ApplicationForm(ModelForm):
> >    class Meta:
> >        model = Application
>
> >    def clean(self):
> >        cleaned_data = self.cleaned_data
> >        users = cleaned_data['users']
> >        folder = cleaned_data['folder']
> >        if
> > users.filter(profile__company__in=folder.company.all()).count() > 0:
> >            raise forms.ValidationError('One of the users of this
> > Application works in one of the Folder companies!')
> >        return cleaned_data
>
> > admin.py
> > class ApplicationAdmin(ModelAdmin):
> >    form = ApplicationForm
>
> > This seems like right the way to go about this. The problem is that
> > neither the users nor folder fields are in the cleaned_data and I get
> > a keyerror when it hits the users = cleaned_data['users'] line.
>
> > I was hoping that someone here could explain to me why these
> > manytomany fields don't show up in cleaned_data and that someone could
> > possibly give me a sollution to my problem.
>
> > Thanks!
> > Heleen
>
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "Django users" group.
> > To post to this group, send email to django-us...@googlegroups.com.
> > To unsubscribe from this group, send email to 
> > django-users+unsubscr...@googlegroups.com.
> > For more options, visit this group 
> > athttp://groups.google.com/group/django-users?hl=en.
>
>

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



Admin Model Validation on ManyToMany Field

2010-07-13 Thread Heleen
Hello,

I have the following classes:
class Application(models.Model):
 users = models.ManyToManyField(User, through='Permission')
 folder = models.ForeignKey(Folder)

class Folder(models.Model):
 company = models.ManyToManyField(Compnay)

class UserProfile(models.Model):
 user = models.OneToOneField(User, related_name='profile')
 company = models.ManyToManyField(Company)

Now when I save application, I would like to check if the users do not
belong to the application's folder's companies.
I have posed this question before and someone came up with the
following sollution:
forms.py:
class ApplicationForm(ModelForm):
class Meta:
model = Application

def clean(self):
cleaned_data = self.cleaned_data
users = cleaned_data['users']
folder = cleaned_data['folder']
if
users.filter(profile__company__in=folder.company.all()).count() > 0:
raise forms.ValidationError('One of the users of this
Application works in one of the Folder companies!')
return cleaned_data

admin.py
class ApplicationAdmin(ModelAdmin):
form = ApplicationForm

This seems like right the way to go about this. The problem is that
neither the users nor folder fields are in the cleaned_data and I get
a keyerror when it hits the users = cleaned_data['users'] line.

I was hoping that someone here could explain to me why these
manytomany fields don't show up in cleaned_data and that someone could
possibly give me a sollution to my problem.

Thanks!
Heleen

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



Re: commit=False in Model save?

2010-06-16 Thread Heleen
Today I'm a bit more awake than when I replied yesterday and I
realized that you're talking about views here.
What I mean however is that I would like to do validation in the model
class' save function in models.py.

I have tried to use this method on my save function though, but it
just gives me the following error:
Transaction managed block ended with pending COMMIT/ROLLBACK
I don't think it should be pending. My save function will eventually
commit or rollback and the error occurs in both cases. So either this
method doesn't work when used on a model class' save function, or
because it's not a view function, something else needs to happen as
well that I don't know of (in case of a rollback the function might
for example need to return an error of some kind).

I've also come across the problem that the 'through' table of my
ManyToManyField is not updated before commit. I call super(Model,
self).save(*args, **kwargs) at the start of def save(*args,
**kwargs):, but I get an empty list when after super-save I try to
retrieve the linked through instances, because they simply do not
exist yet.

Could anyone tell me if what I'm doing is the right way of approaching
it and how it should be done?
Thanks!

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



Re: commit=False in Model save?

2010-06-15 Thread Heleen
Thanks to the 'unknown' user for the reply. This is probably what I'm
looking for. I think I have had a glance at it while searching the
Django Docs but I don't think I fully understood it. I do now and will
give it a go tomorrow morning!

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



Re: commit=False in Model save?

2010-06-15 Thread Heleen
Someone e-mailed me a reply, and I thought I'd make it public before I
reply.

What you could do is use manual transaction management and do
something like:

@transaction.commit_manually
def my_view(request):
   ...
  try:
  my_form.save()
   except MyFormException:
  # thrown when validation fails, etc.
  transaction.rollback()
   finally:
   transaction.commit()

That should allow you to create the PKs and then get out of there if
there's a problem.

On Jun 15, 9:23 am, Heleen <heleen...@gmail.com> wrote:
> Hello,
>
> I have a situation where I would like to do some validation on a many-
> to-many field in a model before it is saved. When the validation fails
> the model should not be saved and result in an appropriate error.
> However to be able to do anything with a many-to-many field the
> primary key of the model should be available, therefore it seems that
> the model should be saved first.
>
> In Forms there is the option to save with commit=False, but I could
> not find anything similar to this for the Models save function.
> Also, using a pre-save signal would not work, because the model is not
> saved yet. A post-save signal doesn't work either because then the
> model gets saved even in the cases that it shouldn't. Rewriting the
> save function would be the best option, but because I cannot 'pre'-
> save with commit=False this doesn't work either.
>
> Could anyone tell me if there is such a function to achieve what I
> need or if there is a better way of doing this?
> Thanks very much!
> Heleen

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



commit=False in Model save?

2010-06-15 Thread Heleen
Hello,

I have a situation where I would like to do some validation on a many-
to-many field in a model before it is saved. When the validation fails
the model should not be saved and result in an appropriate error.
However to be able to do anything with a many-to-many field the
primary key of the model should be available, therefore it seems that
the model should be saved first.

In Forms there is the option to save with commit=False, but I could
not find anything similar to this for the Models save function.
Also, using a pre-save signal would not work, because the model is not
saved yet. A post-save signal doesn't work either because then the
model gets saved even in the cases that it shouldn't. Rewriting the
save function would be the best option, but because I cannot 'pre'-
save with commit=False this doesn't work either.

Could anyone tell me if there is such a function to achieve what I
need or if there is a better way of doing this?
Thanks very much!
Heleen

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



Re: send_mail not sending e-mail in view, but does send e-mail in shell

2010-02-17 Thread Heleen
Thanks for your help, I figured out in the end what was causing the
problem.
Because there was a problem with Spawning crashing and not properly
restarting when using more than 0 threads, we had set the number of
threads to 0. However this appeared to cause the e-mail sending
problem. We set the number of threads back to 4 and that was solved,
then we did sudo easy_install -U MySQL-python Spawning eventlet
setuptools. And after restarting the spawning script, all problems
were solved. It now sends e-mail and restarts correctly.

I have to say that nothing showed up in any log, so that's why it took
us so long to figure this out.
Thanks again for your help though.

On Feb 16, 7:19 pm, creecode <creec...@gmail.com> wrote:
> Hello Heleen,
>
> I don't have any specific solutions for you.  In several of my
> projects I have views that do deliver email without issue.
>
> A couple of things come to mind.  Have you checked that the arguments
> passed to send_mail in your view are correct?  Is it possible that
> there is some kind of permission problem?  Something like the Nginx
> process isn't allowed to send email?
>
> It might help us to help you if you could let us see the relevant code
> in question and any tracebacks if there is an error.
>
> On Feb 15, 1:09 pm, Heleen <heleen...@gmail.com> wrote:
>
> > When I try to send an e-mail  using
> > send_mail() trough the Django website (so via a view function), it
> > does not deliver the e-mail. However when on the same server I use
> > 'python manage.py shell' it does deliver the e-mail.
>
> Toodle-lo...
> creecode

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



send_mail not sending e-mail in view, but does send e-mail in shell

2010-02-15 Thread Heleen
Hi,

I hope this question hasn't been asked before, if so please link me to
the answer (I couldn't find it).
I have the following problem. When I try to send an e-mail  using
send_mail() trough the Django website (so via a view function), it
does not deliver the e-mail. However when on the same server I use
'python manage.py shell' it does deliver the e-mail. I'm using Postfix
(and earlier I tried Exim as well) to handle e-mails. When I send the
e-mail using the shell it shows up in the logs. When I try sending it
through the website it does not show up in any log. Postfix really is
set-up correctly and I am also certain that the code in the view is
correct. Sending e-mail does work on a similar server which has an
earlier version of Python and Django.

I'm running Django 1.1 on a Debian server with Python 2.5.2 running
spawning with Nginx. I use the following startup script:
#!/bin/sh

PROJNAME=website
PROJDIR=/var/www/heleen/website
PORT=9001

cd ${PROJDIR}/../
/usr/bin/spawn --factory=spawning.django_factory.config_factory $
{PROJNAME}.settings --port=$PORT --threads=0 --processes=1   --access-
log-file=/var/log/django/${PROJNAME} &

Is there anyone who has any idea what I'm missing?

Thank very much in advance for your help!
Heleen

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