views:

231

answers:

1

Hi,

I've implemented a circular OneToMany relationship at a Django model and tried to use the limit_choices_to option at this very same class.

I can syncdb without any error or warning but the limit is not being respected. Using shell I'm able to save and at admin I receive the error message:

"Join on field 'type' not permitted. Did you misspell 'neq' for the lookup type?"

class AdministrativeArea(models.Model):
    type = models.CharField(max_length=1, choices=choices.ADMIN_AREA_TYPES)
    name = models.CharField(max_length=60, unique=True)

    parent = models.ForeignKey('AdministrativeArea', 
                               null=True,
                               blank=True, 
                               limit_choices_to = Q(type__neq='p') & Q(type__neq=type)
    )

The basic idea for the limit_choices_to option is to guarantee that any type "p" cannot be parent ofr any other AdministrativeArea AND the parent cannot be of the same type as the current AdministrativeArea type.

I'm pretty new to Django ... what am I missing?

Thanks

A: 

You can create a model form that adjusts specific field's queryset dynamically when working with existing model instance.

### in my_app/models.py ###

class AdministrativeArea(models.Model):
  type = models.CharField(max_length=1, choices=choices.ADMIN_AREA_TYPES)
  name = models.CharField(max_length=60, unique=True)

  parent = models.ForeignKey('AdministrativeArea', 
                           null=True,
                           blank=True, 
                           limit_choices_to = Q(type__neq='p')
)


### in my_app/admin.py ###

from django.contrib import admin
import django.forms as forms
from my_app.models import AdministrativeArea

class class AdministrativeAreaAdminForm(forms.ModelForm):
  def __init__(self, *args, **kwargs):
    super(AdministrativeAreaAdminForm, self).__init__(*args, **kwargs)
    instance = kwargs.get('instance', None)
    if instance is not None:
      parentField = self.fields['parent']
      parentField.queryset = parentField.queryset.filter(type__neq=instance.type)

  class Meta:
    model = AdministrativeArea


class AdministrativeAreaAdmin(admin.ModelAdmin):
  form = AdministrativeAreaAdminForm

Such form could be used also outside admin site if you need the filtering there.

Valts