Working add/edit people and names; working privacy (living and private); unified templates for display/edit

svn: r13952
This commit is contained in:
Doug Blank
2010-01-01 15:16:20 +00:00
parent eba1c9d264
commit c800392ffd
14 changed files with 378 additions and 353 deletions

View File

@@ -18,7 +18,7 @@
"setting" : "db_created" ,
"description" : "database creation date/time" ,
"value_type" : "str" ,
"value" : "2009-12-28 22:19"
"value" : "2010-01-01 10:12"
}
},
{

View File

@@ -11,11 +11,8 @@ class PersonForm(forms.ModelForm):
class Meta:
model = Person
'''def clean(self):
cleaned_data['last_changed'] = datetime.datetime.now()
super(PersonForm, self).clean() # validate based on model
return self.cleaned_data'''
exclude = ["death", "birth", "handle"]
class NameForm(forms.ModelForm):
class Meta:
model = Name
@@ -50,51 +47,14 @@ class NameForm(forms.ModelForm):
required=False,
widget=TextInput(attrs={'size':'30'}))
'''class NameFormset(BaseModelFormSet):
def __init__(self, *args, **kwargs):
self.form = NameForm
super(NameFormset, self).__init__(*args, **kwargs)
def makeNameFormset(pid):
class NameFormset(BaseFormSet):
def __init__(self, *args, **kwargs):
self.form = NameForm
self.queryset = Name.objects.filter(person=pid)
super(NameFormset, self).__init__(*args, **kwargs)
def clean(self):
super(NameFormset, self).clean() # validate based on model
if any(self.errors):
# formset is not valid as long as any one form is invalid
return
# allow only one name per person to be preferred
ctPref = 0
for i in range(0, self.total_form_count()):
form = self.forms[i]
ctPref += form.cleaned_data['preferred']
if ctPref > 1:
raise forms.ValidationError, "Only one name may be the preferred name."
return NameFormset'''
NameInlineFormSet = inlineformset_factory(Person, Name,
fields=('preferred','prefix','first_name',
'surname','suffix','name_type'),
form=NameForm)
def cleanPreferred(fmst):
if fmst.total_form_count() == 3: # person has no names (assumes default 3 extra forms)
return "Error: Each person must have at least one name."
ctPref = 0
for i in range (0,fmst.total_form_count()-3):
form = fmst.forms[i]
try: # when preferred is false, its value is not in the form data
if form.data[fmst.prefix + '-' + str(i) + '-preferred'] == 'on':
val = 1
else:
val = 0
except:
val = 0
ctPref += val
if ctPref != 1:
return "Error: Exactly one name may be the preferred name."
else:
return "none"
class NameFormFromPerson(NameForm):
class Meta:
model = Name
# Exclude these, so they don't get checked:
exclude = ["order", "calendar", "modifier",
"quality",
#"quality_estimated", "quality_calculated",
#"quality_interpreted",
"year1", "day1", "month1",
"sortval", "newyear", "person",
"sort_as", "display_as"]

View File

@@ -300,23 +300,23 @@ class DateNewYearType(mGrampsType):
class DateObject(models.Model):
class Meta: abstract = True
calendar = models.IntegerField()
modifier = models.IntegerField()
quality = models.IntegerField()
calendar = models.IntegerField(default=0)
modifier = models.IntegerField(default=0)
quality = models.IntegerField(default=0)
#quality_estimated = models.BooleanField()
#quality_calculated = models.BooleanField()
#quality_interpreted = models.BooleanField()
day1 = models.IntegerField()
month1 = models.IntegerField()
year1 = models.IntegerField()
slash1 = models.BooleanField()
day1 = models.IntegerField(default=0)
month1 = models.IntegerField(default=0)
year1 = models.IntegerField(default=0)
slash1 = models.BooleanField(default=False)
day2 = models.IntegerField(blank=True, null=True)
month2 = models.IntegerField(blank=True, null=True)
year2 = models.IntegerField(blank=True, null=True)
slash2 = models.NullBooleanField(blank=True, null=True)
text = models.CharField(max_length=80, blank=True)
sortval = models.IntegerField()
newyear = models.IntegerField()
sortval = models.IntegerField(default=0)
newyear = models.IntegerField(default=0)
def set_date_from_datetime(self, date_time, text=""):
"""
@@ -401,8 +401,8 @@ class Person(PrimaryObject):
references = generic.GenericRelation('PersonRef', related_name="refs",
content_type_field="object_type",
object_id_field="object_id")
birth = models.ForeignKey("Event", related_name="birth", null=True)
death = models.ForeignKey("Event", related_name="death", null=True)
birth = models.ForeignKey("Event", related_name="birth", blank=True, null=True)
death = models.ForeignKey("Event", related_name="death", blank=True, null=True)
# Others keys here:
# .name_set
@@ -414,12 +414,7 @@ class Person(PrimaryObject):
"""
Return the preferred name of a person.
"""
names = self.name_set.all().order_by("order")
if names.count() > 0:
name = names[0]
else:
name = None
return name
return self.name_set.get(preferred=True)
class Family(PrimaryObject):
father = models.ForeignKey('Person', related_name="father_ref",
@@ -509,10 +504,12 @@ class SecondaryObject(models.Model):
last_saved = models.DateTimeField('last changed', auto_now=True)
last_changed = models.DateTimeField('last changed', null=True,
blank=True) # user edits
order = models.PositiveIntegerField()
order = models.PositiveIntegerField(default=1)
class Name(DateObject, SecondaryObject):
name_type = models.ForeignKey('NameType', related_name="name_code")
name_type = models.ForeignKey('NameType',
related_name="name_code",
default=2)
preferred = models.BooleanField('Preferred name?')
first_name = models.TextField(blank=True)
surname = models.TextField(blank=True)
@@ -523,12 +520,14 @@ class Name(DateObject, SecondaryObject):
call = models.TextField(blank=True)
group_as = models.TextField(blank=True)
sort_as = models.ForeignKey('NameFormatType',
related_name="sort_as")
related_name="sort_as",
default=1)
display_as = models.ForeignKey('NameFormatType',
related_name="display_as")
related_name="display_as",
default=1)
## Key:
person = models.ForeignKey("Person")
_sanitized = False
def __unicode__(self):
return "%s%s%s, %s" % (self.prefix,
@@ -541,12 +540,13 @@ class Name(DateObject, SecondaryObject):
#name.
def sanitize(self):
self.first_name = "[Private]"
self.prefix = ""
self.suffix = ""
self.prefix = ""
self.prefix = ""
self.prefix = ""
if not self._sanitized:
self._sanitized = True
if self.person.probably_alive:
self.first_name = "[Living]"
self.call = ""
self.group_as = ""
self.title = ""
class Lds(DateObject, SecondaryObject):
"""

View File

@@ -8,6 +8,16 @@ import web.utils
register = Library()
def eval_template_exp(item, context):
"""
Wrapper to allow negation of variables in templates. Use
"!variable".
"""
if item.var.startswith("!"):
return not template.Variable(item.var[1:]).resolve(context)
else:
return item.resolve(context)
class TemplateNode(template.Node):
def __init__(self, args, var_name, func):
self.args = map(template.Variable, args)
@@ -15,7 +25,8 @@ class TemplateNode(template.Node):
self.func = func
def render(self, context):
value = self.func(*[item.resolve(context) for item in self.args])
value = self.func(*[eval_template_exp(item, context)
for item in self.args])
if self.var_name:
context[self.var_name] = value
return ''
@@ -123,34 +134,9 @@ def paginator(context, adjacent_pages=2):
view.
"""
## Alternative page_numbers:
page_numbers = range(max(0, context['page']-adjacent_pages),
min(context['pages'],
context['page']+adjacent_pages)+1)
results_this_page = context['object_list'].__len__()
range_base = ((context['page'] - 1) * context['results_per_page'])
# # Original
# # page_numbers = [n for n in range(context['page'] - adjacent_pages,
# # context['page'] + adjacent_pages + 1)
# # if n > 0 and n <= context['pages']]
return {
'hits': context['hits'],
'results_per_page': context['results_per_page'],
'results_this_page': results_this_page,
'first_this_page': range_base + 1,
'last_this_page': range_base + results_this_page,
'page': context['page'],
'pages': context['pages'],
'page_numbers': page_numbers,
'next': context['next'],
'previous': context['previous'],
'has_next': context['has_next'],
'has_previous': context['has_previous'],
'show_first': 1 not in page_numbers,
'show_last': context['pages'] not in page_numbers,
}
results_this_page = context["page"].object_list.count()
context.update({'results_this_page': results_this_page,})
return context
register.inclusion_tag('paginator.html',
takes_context=True)(paginator)

View File

@@ -41,11 +41,11 @@ from django.db.models import Q
#------------------------------------------------------------------------
import web
from web.grampsdb.models import *
from web.grampsdb.forms import NameForm, PersonForm
from web.utils import probably_alive
from web.grampsdb.forms import *
from web.djangodb import DjangoDb
import gen.proxy
from Utils import create_id
_ = lambda text: text
@@ -70,6 +70,9 @@ def context_processor(request):
context["css_theme"] = "Web_Mainz.css"
# FIXME: get the views from a config?
context["views"] = VIEWS
context["True"] = True
context["False"] = False
context["default"] = ""
return context
# CSS Themes:
@@ -107,6 +110,40 @@ def user_page(request, username):
context["tview"] = _('User')
return render_to_response('user_page.html', context)
def fix_person(request, person):
try:
name = person.name_set.get(preferred=True)
except:
names = person.name_set.all().order_by("order")
if names.count() == 0:
name = Name(person=person,
surname="? Fixed",
first_name="? Missing name",
preferred=True)
name.save()
else:
order = 1
for name in names:
if order == 1:
name.preferred = True
else:
name.preferred = False
name.order = order
name.save()
order += 1
if request:
return redirect("/person/%s" % person.handle, request)
def set_date(obj):
obj.calendar = 0
obj.modifier = 0
obj.quality = 0
obj.text = ""
obj.sortval = 0
obj.newyear = 0
obj.day1, obj.month1, obj.year1, obj.slash1 = 0, 0, 0, 0
obj.day2, obj.month2, obj.year2, obj.slash2 = 0, 0, 0, 0
def view_name_detail(request, handle, order, action="view"):
if order == "add":
order = 0
@@ -115,50 +152,53 @@ def view_name_detail(request, handle, order, action="view"):
action = request.POST.get("action")
if action == "view":
person = Person.objects.get(handle=handle)
name = person.name_set.get(order=order)
try:
name = person.name_set.filter(order=order)[0]
except:
return fix_person(request, person)
form = NameForm(instance=name)
form.model = name
elif action == "edit":
person = Person.objects.get(handle=handle)
name = person.name_set.get(order=order)
name = person.name_set.filter(order=order)[0]
form = NameForm(instance=name)
form.model = name
elif action == "delete":
person = Person.objects.get(handle=handle)
name_to_delete = person.name_set.get(order=order)
was_preferred = name_to_delete.preferred
name_to_delete.delete()
names = person.name_set.all().order_by("order")
for count in range(names.count()):
if was_preferred:
names[count].preferred = True
was_preferred = False
names[count].order = count
names[count].save()
print "delete", names.count()
if names.count() > 1:
print "more than 1"
name_to_delete = names[0]
was_preferred = name_to_delete.preferred
name_to_delete.delete()
names = person.name_set.all().order_by("order")
for count in range(names[1:].count()):
print count
if was_preferred:
names[count].preferred = True
was_preferred = False
names[count].order = count
names[count].save()
form = NameForm()
name = Name()
action = "back"
elif action == "add":
elif action == "add": # add name
person = Person.objects.get(handle=handle)
name = Name()
name.sort_as = NameFormatType.objects.get(val=0)
name.display_as = NameFormatType.objects.get(val=0)
name.name_type = NameType.objects.get(val=2) # Birth Name
name = Name(person=person,
display_as=NameFormatType.objects.get(val=0),
sort_as=NameFormatType.objects.get(val=0),
name_type=NameType.objects.get(val=2))
form = NameForm(instance=name)
form.model = name
action = "edit"
elif action == "save":
person = Person.objects.get(handle=handle)
try:
name = person.name_set.get(order=order)
name = person.name_set.filter(order=order)[0]
except:
order = person.name_set.count() + 1
name = Name(calendar=0, modifier=0, quality=0,
year1=0, day1=0, month1=0,
sortval = 0, newyear=0, order=order,
sort_as=NameFormatType(val=0),
display_as=NameFormatType(val=0),
person_id=person.id)
name = Name(person=person, order=order)
form = NameForm(request.POST, instance=name)
form.model = name
if form.is_valid():
@@ -174,6 +214,7 @@ def view_name_detail(request, handle, order, action="view"):
.update(preferred=False)
# else some other name is preferred
print "save"
set_date(name)
n = form.save()
print n.preferred
else:
@@ -187,6 +228,7 @@ def view_name_detail(request, handle, order, action="view"):
context["person"] = person
context["form"] = form
context["order"] = name.order
context["next"] = "/person/%s/name/%d" % (person.handle, name.order)
view_template = "view_name_detail.html"
print "action:", action
if action == "save":
@@ -200,13 +242,6 @@ def view_name_detail(request, handle, order, action="view"):
return render_to_response(view_template, context)
class PrivateProxy(object):
def __init__(self, obj):
self.obj = obj
def __getattr__(self, attr):
return getattr(self.obj, attr)
def view_detail(request, view, handle, action="view"):
context = RequestContext(request)
context["action"] = action
@@ -265,56 +300,104 @@ def view_detail(request, view, handle, action="view"):
else:
raise Http404(_("Requested page type not known"))
context[view] = obj
context["next"] = "/%s/%s" % (view, obj.handle)
return render_to_response(view_template, context)
def get_gramps_db(request):
dbase = DjangoDb()
#if request.user.is_authenticated():
private_filter=False
living_filter=False
#else:
# private_filter=True
# living_filter=True
# If the private flag is set, apply the PrivateProxyDb
if private_filter:
dbase = gen.proxy.PrivateProxyDb(dbase)
# If the restrict flag is set, apply the LivingProxyDb
if living_filter:
dbase = gen.proxy.LivingProxyDb(
dbase,
gen.proxy.LivingProxyDb.MODE_INCLUDE_LAST_NAME_ONLY)
return dbase
def view_person_detail(request, view, handle, action="view"):
context = RequestContext(request)
print view, handle, action
if handle == "add":
if request.POST.has_key("action"):
action = request.POST.get("action")
else:
action = "add"
elif request.POST.has_key("action"):
action = request.POST.get("action")
if request.user.is_authenticated():
if action == "edit":
# get all of the data:
person = Person.objects.get(handle=handle)
try:
name = person.name_set.get(preferred=True)
except:
name = Name(person=person, preferred=True)
pf = PersonForm(instance=person)
pf.model = person
nf = NameForm(instance=name)
nf.model = name
elif action == "add":
# make new data:
person = Person()
name = Name(person=person, preferred=True,
display_as=NameFormatType.objects.get(val=0),
sort_as=NameFormatType.objects.get(val=0),
name_type=NameType.objects.get(val=2))
nf = NameForm(instance=name)
nf.model = name
pf = PersonForm(instance=person)
pf.model = person
action = "edit"
elif action == "save":
try:
person = Person.objects.get(handle=handle)
except:
person = Person(handle=create_id())
if person.id: # editing
name = person.name_set.get(preferred=True)
else: # adding a new person with new name
name = Name(person=person, preferred=True)
pf = PersonForm(request.POST, instance=person)
pf.model = person
nf = NameFormFromPerson(request.POST, instance=name)
nf.model = name
print "checking:", person.handle
if nf.is_valid() and pf.is_valid():
person = pf.save()
name = nf.save(commit=False)
name.person = person
name.save()
else:
action = "edit"
else: # view
person = Person.objects.get(handle=handle)
try:
name = person.name_set.get(preferred=True)
except:
return fix_person(request, person)
pf = PersonForm(instance=person)
pf.model = person
nf = NameForm(instance=name)
nf.model = name
else: # view person detail
# BEGIN NON-AUTHENTICATED ACCESS
person = Person.objects.get(handle=handle)
if person:
if person.private:
raise Http404(_("Requested %s is not accessible.") % view)
name = person.name_set.get(preferred=True)
if person.probably_alive:
name.sanitize()
else:
raise Http404(_("Requested %s does not exist.") % view)
pf = PersonForm(instance=person)
pf.model = person
nf = NameForm(instance=name)
nf.model = name
# END NON-AUTHENTICATED ACCESS
if action == "save":
context["action"] = "view"
return redirect("/person/%s" % person.handle, context)
context["action"] = action
context["view"] = view
context["tview"] = _("Person")
view_template = 'view_person_detail.html'
if request.user.is_authenticated():
person = Person.objects.get(handle=handle)
name = person.name_set.get(preferred=True)
else:
db = get_gramps_db(request)
gramps_person = db.get_person_from_handle(handle)
if not gramps_person:
raise Http404(_("Requested %s is not accessible.") % view)
person = Person.objects.get(handle=handle)
name = person.name_set.get(preferred=True)
# fill forms with data from db
name.surname = gramps_person.get_primary_name().get_surname()
name.first_name = gramps_person.get_primary_name().get_first_name()
pf = PersonForm(instance=person)
pf.model = person
nf = NameForm(instance=name)
nf.model = name
context["personform"] = pf
context["nameform"] = nf
context["person"] = person
context["next"] = "/person/%s" % person.handle
view_template = 'view_person_detail.html'
return render_to_response(view_template, context)
def view(request, view):
db = get_gramps_db(request)
search = ""
if view == "event":
if request.user.is_authenticated():
@@ -366,12 +449,14 @@ def view(request, view):
if request.GET.has_key("search"):
search = request.GET.get("search")
if "," in search:
search, trash = [term.strip() for term in search.split(",", 1)]
search_text, trash = [term.strip() for term in search.split(",", 1)]
else:
search_text = search
object_list = Family.objects \
.filter((Q(gramps_id__icontains=search) |
Q(family_rel_type__name__icontains=search) |
Q(father__name__surname__istartswith=search) |
Q(mother__name__surname__istartswith=search)) &
.filter((Q(gramps_id__icontains=search_text) |
Q(family_rel_type__name__icontains=search_text) |
Q(father__name__surname__istartswith=search_text) |
Q(mother__name__surname__istartswith=search_text)) &
Q(private=False) &
Q(mother__private=False) &
Q(father__private=False)
@@ -450,11 +535,14 @@ def view(request, view):
# BEGIN NON-AUTHENTICATED users
if request.GET.has_key("search"):
search = request.GET.get("search")
print "search:", search
if "," in search:
search, trash = [term.strip() for term in search.split(",", 1)]
search_text, trash = [term.strip() for term in search.split(",", 1)]
else:
search_text = search
object_list = Name.objects \
.select_related() \
.filter(Q(surname__istartswith=search) &
.filter(Q(surname__istartswith=search_text) &
Q(private=False) &
Q(person__private=False)
) \
@@ -548,9 +636,10 @@ def view(request, view):
context["tview"] = _(view.title())
context["search"] = search
context["total"] = total
context["db"] = db
context["object_list"] = object_list
context["next"] = "/person/"
if search:
context["search_query"] = ("&search=%s" % escape(search))
context["search_query"] = ("&search=%s" % search)
else:
context["search_query"] = ""
return render_to_response(view_template, context)