Thanks for walking me through the traceback Karen. I'm happy to post my models.py and admin.py code here (or whatever else might help), but I don't ever explicitly check settings.DEBUG in any of my code, so I'm at a bit of a loss where the error might be coming from. Any further suggestions?
#people/models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib.localflavor.us.models import PhoneNumberField
class Contact(models.Model):
"""
The Contact model represents contact information.
"""
owner = models.ForeignKey(User,blank=False) #relationship field
address = models.TextField("Address (W)",default="33 West 42nd Street\nNew York, NY 10036",blank=False)
phone = PhoneNumberField("Phone (W)",blank=True)
fax = PhoneNumberField("Fax (W)",blank=True)
email = models.EmailField("Email",blank=True)
website = models.URLField("Website",blank=True)
home = models.TextField("Address (H)",blank=True)
line = PhoneNumberField("Phone (H)",blank=True)
mobile = PhoneNumberField("Mobile",blank=True)
emergency = models.TextField("Emergency Contact",blank=True)
def __unicode__(self):
return "\n".join([i for i in [self.address, self.phone, self.fax, self.email, self.website, self.home, self.line, self.mobile, self.emergency] if i])
class Person(models.Model):
"""
The Person model represents a person.
"""
owner = models.ForeignKey(User,blank=False) #relationship field
first_name = models.CharField("First Name",max_length=30,blank=False)
middle_name = models.CharField("Middle Name",max_length=30,blank=True)
last_name = models.CharField("Last Name",max_length=60,blank=False)
degree = models.CharField("Degree(s)",max_length=12,blank=True)
title = models.ForeignKey("Title",verbose_name="Title",blank=False) #relationship field
date_start = models.DateField("Start Date",blank=False)
date_end = models.DateField("End Date",help_text="Please approximate and change upon departure.",blank=False)
contact = models.ForeignKey("Contact",verbose_name="Contact",blank=False) #relationship field
publications = models.ManyToManyField("publications.Publication",verbose_name="Publication(s)",blank=True) #relationship field
cv = models.FileField("CV",upload_to="cvs",blank=True)
image = models.ImageField("Photo",upload_to="images/people",blank=True)
statement = models.TextField("Personal Statement",help_text="This text may include HTML formatting.",blank=True)
def __unicode__(self):
return " ".join([i for i in [self.first_name, self.middle_name, self.last_name] if i])
class Meta:
verbose_name_plural = "People"
class Title(models.Model):
"""
The Title model represents a job title.
"""
name = models.CharField("Title",max_length=50,blank=False)
def __unicode__(self):
return
self.name
#people/admin.py
from laboratory.people.models import Contact, Person, Title
from django.contrib import admin
from django import forms
from html5lib import HTMLParser, sanitizer, treewalkers, serializer
import re
def save_model_method(self, request, obj, form, change):
"""
The save_model_method is used by the ModelAdmin classes below
to override their save_model methods. See the documentation at
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#save-model-self-request-obj-form-change.
"""
if isinstance(obj, Person) and
obj.pk:
person = Person.objects.get(pk=
obj.pk)
if
person.cv and 'cv' in form.changed_data:
person.cv.delete() #delete old file
if person.image and 'image' in form.changed_data:
person.image.delete() #delete old file
if not change:
obj.owner = request.user
obj.save()
def queryset_method(self, request, queryClass):
"""
The queryset_method is used by the ModelAdmin classes below to
override their queryset methods. This method is undocumented
but can be found in django/contrib/admin/options.py.
"""
if request.user.is_superuser:
return queryClass.objects.all()
else:
return queryClass.objects.filter(owner=request.user)
def has_add_permission_method(self, request, superClass):
"""
The has_add_permission_method is used by the ModelAdmin classes
below to override their has_add_permission methods. This method
is undocumented but can be found in
django/contrib/admin/options.py.
"""
has_class_permission = super(type(self), self).has_add_permission(request)
has_no_obj = superClass.objects.filter(owner=request.user).count()==0
if has_class_permission and (request.user.is_superuser or has_no_obj):
return True
else:
return False
def has_change_permission_method(self, request, obj=None):
"""
The has_change_permission_method is used by the ModelAdmin
classes below to override their has_change_permission methods.
This method is undocumented but can be found in
django/contrib/admin/options.py.
"""
has_class_permission = super(type(self), self).has_change_permission(request, obj)
if has_class_permission and (obj is None or request.user.is_superuser or
request.user.id==
obj.owner.id):
return True
else:
return False
def get_form_method(self, request, obj, exclude, **kwargs):
"""
The get_form_method is used by the ModelAdmin classes below to
override their get_form methods. This method is undocumented
but can be found in django/contrib/admin/options.py.
"""
if request.user.is_superuser:
self.exclude = None
else:
self.exclude = exclude
return super(type(self), self).get_form(request, obj, **kwargs)
def changelist_view_method(self, request, extra_context, exclude, list_display):
"""
The changelist_view_method is used by the ModelAdmin classes
below to override their changelist_view methods. This method
is undocumented but can be found in
django/contrib/admin/options.py.
"""
if request.user.is_superuser:
self.list_display = exclude + list_display
else:
self.list_display = list_display
return super(type(self), self).changelist_view(request, extra_context)
class ContactAdmin(admin.ModelAdmin):
fieldsets = (
('Work (public)', {'fields': ('address', 'phone', 'fax', 'email', 'website',)}),
('Home (private)', {'fields': ('home', 'line', 'mobile', 'emergency',)}),
)
exclude_list = ('owner',) #custom field - see get_form
list_display_list = ('address', 'phone', 'fax', 'email', 'website', 'home', 'line', 'mobile', 'emergency',) #custom field - see changelist_view
search_fields = ['address', 'phone', 'fax', 'email', 'website', 'home', 'line', 'mobile', 'emergency',]
save_model = save_model_method
has_change_permission = has_change_permission_method
def queryset(self, request):
return queryset_method(self, request, Contact)
def has_add_permission(self, request):
return has_add_permission_method(self, request, Contact)
def get_form(self, request, obj=None, **kwargs):
return get_form_method(self, request, obj, self.exclude_list, **kwargs)
def changelist_view(self, request, extra_context=None):
return changelist_view_method(self, request, extra_context, self.exclude_list, self.list_display_list)
class PersonForm(forms.ModelForm):
class Meta:
model = Person
def clean_cv(self):
cv = self.cleaned_data['cv']
if cv:
cv.name = re.sub(r"(?i)(?P<ext>(?:cgi|htaccess|php[0-9s]?|[ps]html?|pl|pyc?|rb)(?:\..+)?)$",
r"\g<ext>.txt",
cv.name)
return cv
def clean_statement(self):
statement = self.cleaned_data['statement']
parser = HTMLParser(tokenizer=sanitizer.HTMLSanitizer)
tree = parser.parseFragment(statement)
walker = treewalkers.getTreeWalker("simpletree")
stream = walker(tree)
serial = serializer.xhtmlserializer.XHTMLSerializer(omit_optional_tags=True)
if statement:
cleaned = serial.render(stream)
else:
cleaned = ""
return cleaned
class PersonAdmin(admin.ModelAdmin):
exclude_list = ('owner',) #custom field - see get_form
list_display_list = ('first_name', 'middle_name', 'last_name', 'degree', 'title',
'date_start', 'date_end', 'contact', 'cv', 'image', 'statement',) #custom field - see changelist_view
list_filter = ['title',]
search_fields = ['first_name', 'middle_name', 'last_name', 'degree', 'title',
'date_start', 'date_end',]
filter_vertical = ['publications',]
form = PersonForm
save_model = save_model_method
has_change_permission = has_change_permission_method
def queryset(self, request):
return queryset_method(self, request, Person)
def has_add_permission(self, request):
return has_add_permission_method(self, request, Person)
def get_form(self, request, obj=None, **kwargs):
return get_form_method(self, request, obj, self.exclude_list, **kwargs)
def changelist_view(self, request, extra_context=None):
return changelist_view_method(self, request, extra_context, self.exclude_list, self.list_display_list)
class TitleAdmin(admin.ModelAdmin):
list_display = ('name',)
search_fields = ['name']
admin.site.register(Contact, ContactAdmin)
admin.site.register(Person, PersonAdmin)
admin.site.register(Title, TitleAdmin)