forked from expo/troggle
[svn] QM parser now parses Hauchhoehle QMs.py
Photo model added. Logbook parser now puts mugshots in as photo models, and descriptions from the old folk html pages in as "blurbs" on the person model. Experimented with eye candy and a random logbook quote generator. Copied from http://cucc@cucc.survex.com/svn/trunk/expoweb/troggle/, rev. 8094 by aaron @ 12/31/2008 2:59 AM
This commit is contained in:
parent
8c818906b5
commit
7aee3fb920
@ -8,7 +8,7 @@ class RoleInline(admin.TabularInline):
|
||||
class SurvexBlockAdmin(admin.ModelAdmin):
|
||||
inlines = (RoleInline,)
|
||||
|
||||
|
||||
admin.site.register(Photo)
|
||||
admin.site.register(Cave)
|
||||
admin.site.register(Area)
|
||||
admin.site.register(OtherCaveName)
|
||||
@ -24,3 +24,4 @@ admin.site.register(Role)
|
||||
admin.site.register(LogbookEntry)
|
||||
admin.site.register(PersonTrip)
|
||||
admin.site.register(QM)
|
||||
|
||||
|
@ -27,8 +27,9 @@ class Expedition(models.Model):
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(max_length=100)
|
||||
last_name = models.CharField(max_length=100)
|
||||
is_vfho = models.BooleanField()
|
||||
is_vfho = models.BooleanField(help_text="VFHO is the Vereines für Höhlenkunde in Obersteier, a nearby Austrian caving club.")
|
||||
mug_shot = models.CharField(max_length=100, blank=True,null=True)
|
||||
blurb = models.TextField(blank=True,null=True)
|
||||
def __unicode__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
@ -56,7 +57,6 @@ class PersonExpedition(models.Model):
|
||||
|
||||
|
||||
|
||||
|
||||
#class LogbookSentanceRating(models.Model):
|
||||
# rating = models.IntegerField()
|
||||
# person_trip = models.ForeignKey(PersonTrip)
|
||||
@ -157,10 +157,7 @@ class LogbookEntry(models.Model):
|
||||
author = models.ForeignKey(PersonExpedition,blank=True,null=True) # the person who writes it up doesn't have to have been on the trip
|
||||
title = models.CharField(max_length=200)
|
||||
cave = models.ForeignKey(Cave,blank=True,null=True)
|
||||
# this will be a foreign key of the place the logbook is describing - JT
|
||||
place = models.CharField(max_length=100,blank=True,null=True)
|
||||
# adding optional cave reference
|
||||
# cave = models.ForeignKey(Cave,blank=True,null=True)
|
||||
text = models.TextField()
|
||||
|
||||
# several PersonTrips point in to this object
|
||||
@ -274,3 +271,24 @@ class QM(models.Model):
|
||||
def __str__(self):
|
||||
QMnumber=str(self.found_by.cave)+'-'+str(self.found_by.date.year)+"-"+str(self.number)+self.grade
|
||||
return str(QMnumber)
|
||||
|
||||
class Photo(models.Model):
|
||||
caption = models.CharField(max_length=1000,blank=True,null=True)
|
||||
contains_person_trip = models.ManyToManyField(PersonTrip,blank=True,null=True)
|
||||
contains_person = models.ManyToManyField(Person,blank=True,null=True)
|
||||
file = models.ImageField(upload_to='photos',)
|
||||
is_mugshot = models.BooleanField(default=False)
|
||||
contains_cave = models.ForeignKey(Cave,blank=True,null=True)
|
||||
contains_entrance = models.ForeignKey(Entrance, related_name="photo_file",blank=True,null=True)
|
||||
nearest_survey_point = models.ForeignKey(SurveyStation,blank=True,null=True)
|
||||
nearest_QM = models.ForeignKey(QM,blank=True,null=True)
|
||||
|
||||
|
||||
lon_utm = models.FloatField(blank=True,null=True)
|
||||
lat_utm = models.FloatField(blank=True,null=True)
|
||||
#content_type = models.ForeignKey(ContentType)
|
||||
#object_id = models.PositiveIntegerField()
|
||||
#location = generic.GenericForeignKey('content_type', 'object_id')
|
||||
|
||||
def __str__(self):
|
||||
return self.caption
|
||||
|
24
expo/randomLogbookSentance.py
Normal file
24
expo/randomLogbookSentance.py
Normal file
@ -0,0 +1,24 @@
|
||||
import troggle.settings as settings
|
||||
from django import forms
|
||||
from expo.models import LogbookEntry
|
||||
import random
|
||||
import re
|
||||
|
||||
def weighted_choice(lst):
|
||||
n = random.uniform(0,1)
|
||||
for item, weight in lst:
|
||||
if n < weight:
|
||||
break
|
||||
n = n - weight
|
||||
return item
|
||||
|
||||
def randomLogbookSentence():
|
||||
#Choose a random logbook entry
|
||||
randSent={}
|
||||
randSent['entry']=LogbookEntry.objects.order_by('?')[0]
|
||||
|
||||
#Choose a random sentence from that entry. Store the sentence as randSent['sentence'], and the number of that sentence in the entry as randSent['number']
|
||||
sentenceList=re.findall('[A-Z].*?\.',randSent['entry'].text)
|
||||
randSent['number']=random.randrange(0,len(sentenceList))
|
||||
randSent['sentence']=sentenceList[randSent['number']]
|
||||
return randSent
|
@ -3,6 +3,8 @@ from troggle.expo.models import Cave, Expedition, Person, LogbookEntry
|
||||
import troggle.settings as settings
|
||||
from django import forms
|
||||
from django.db.models import Q
|
||||
import re
|
||||
import randSent
|
||||
|
||||
def stats(request):
|
||||
statsDict={}
|
||||
@ -11,3 +13,7 @@ def stats(request):
|
||||
statsDict['personCount'] = int(Person.objects.count())
|
||||
statsDict['logbookEntryCount'] = int(LogbookEntry.objects.count())
|
||||
return render_to_response('statistics.html', statsDict)
|
||||
|
||||
def frontPage(request):
|
||||
|
||||
return render_to_response('index.html', {'randSent':randSent.randomLogbookSentence(),'settings':settings})
|
BIN
media/SilkRoadsilouetteAndrew.png
Normal file
BIN
media/SilkRoadsilouetteAndrew.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 69 KiB |
@ -2,11 +2,18 @@
|
||||
.centre { text-align: center; }
|
||||
.plus2pt { font-size: 160%; }
|
||||
|
||||
body, td, center, ul, p, input { color: #000; font-family: sans-serif; }
|
||||
body, td, center, ul, p, input {
|
||||
color: rgb(204, 204, 102);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
body {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
a:link, a:visited { text-decoration: none; }
|
||||
div.centre img { vertical-align: middle; }
|
||||
|
||||
h1 { text-align: center; font-size: 210%; line-height: 100%; }
|
||||
h1 { text-align: center; font-size: 210%; opacity:0.7; filter:alpha(opacity=70);}
|
||||
h2 { color: #009900; }
|
||||
h3 { color: #2c105e; }
|
||||
h4 { color: #0d664c; }
|
||||
@ -19,6 +26,23 @@ img.onleft, div.onleft { vertical-align: top; float: left;
|
||||
margin-left: 8pt; }
|
||||
img.icon { vertical-align: middle; }
|
||||
img.aligntop { vertical-align: top; }
|
||||
blockquote {
|
||||
font: Georgia, "Times New Roman", Times, serif;
|
||||
font-weight:bold;
|
||||
font-variant:small-caps;
|
||||
width: 400px;
|
||||
background: url(../close-quote.gif) no-repeat right bottom;
|
||||
padding-left: 25px;
|
||||
text-indent: -25px;
|
||||
text-align: right;
|
||||
vertical-align:bottom;
|
||||
color:#CCCC66;
|
||||
}
|
||||
blockquote:first-letter {
|
||||
background: url(../open-quote.gif) no-repeat left top;
|
||||
padding-left: 40px;
|
||||
font: italic 1.4em Georgia, "Times New Roman", Times, serif;
|
||||
}
|
||||
table.imgtable { margin-left: auto; margin-right: auto; }
|
||||
table.imgtable td { vertical-align: middle; text-align: center;
|
||||
padding: 10px; }
|
||||
@ -38,6 +62,7 @@ table.trad td, table.trad th { margin: 0pt; border: 1px solid #aaa;
|
||||
html, body, div.contents {
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
width:100%;
|
||||
}
|
||||
html>body, html>body div.contents {
|
||||
height: auto;
|
||||
@ -47,12 +72,12 @@ body {
|
||||
div.contents {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
div.footer {
|
||||
position: fixed;
|
||||
bottom: 2px;
|
||||
right: 2px;
|
||||
left: 2px;
|
||||
}
|
||||
div.main {
|
||||
margin-bottom: 3em;
|
||||
|
46
media/js/base.js
Normal file
46
media/js/base.js
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
function showDiv(collapsed,expanded){
|
||||
document.getElementById(collapsed).style.display = 'none';
|
||||
document.getElementById(expanded).style.display = 'block';
|
||||
}
|
||||
|
||||
function hideDiv(collapsed,expanded){
|
||||
document.getElementById(collapsed).style.display = 'block';
|
||||
document.getElementById(expanded).style.display = 'none';
|
||||
}
|
||||
|
||||
function makeDivTransparent(div){
|
||||
document.getElementById(div).style.backgroundColor = 'transparent';
|
||||
}
|
||||
|
||||
|
||||
|
||||
hex=0 // Initial color value.
|
||||
leftPos=25
|
||||
year=1976
|
||||
currentDate= new Date()
|
||||
currentYear = currentDate.getFullYear()
|
||||
function fadeText(){
|
||||
if(hex<153) { //If color is not black yet
|
||||
hex=hex+10; // increase color darkness
|
||||
leftPos-=1;
|
||||
document.getElementById("expoHeader").style.color="rgb("+0+","+hex+","+0+")";
|
||||
// document.getElementById("expoFinalDate").style.color="rgb("+0+","+hex+","+0+")";
|
||||
document.getElementById("expoHeader").style.left=leftPos;
|
||||
setTimeout("fadeText()",50)
|
||||
setTimeout("countUpYear()",1000)
|
||||
}
|
||||
else {
|
||||
hex=0;
|
||||
leftPos=25;
|
||||
}
|
||||
}
|
||||
|
||||
function countUpYear(){
|
||||
if (year<currentYear) {
|
||||
// alert (year+''+currentYear)
|
||||
year=year+1
|
||||
document.getElementById("expoFinalDate").innerHTML="<h1>"+year+"</h1>"
|
||||
setTimeout("countUpYear()",1000)
|
||||
}
|
||||
}
|
BIN
media/loserBanner.jpg
Normal file
BIN
media/loserBanner.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 215 KiB |
BIN
media/open-quote.gif
Normal file
BIN
media/open-quote.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 187 B |
@ -8,29 +8,56 @@ import re
|
||||
|
||||
QM.objects.all().delete()
|
||||
|
||||
def parseCaveQMs(cave,pathToCSV):
|
||||
if cave=='stein':
|
||||
try:
|
||||
steinBr=Cave.objects.get(official_name="Steinbrückenhöhle")
|
||||
except Cave.DoesNotExist:
|
||||
print "Steinbruckenhoehle is not in the database. Please run parsers.cavetab first."
|
||||
return
|
||||
elif cave=='hauch':
|
||||
try:
|
||||
hauchHl=Cave.objects.get(official_name="Hauchhöhle")
|
||||
except Cave.DoesNotExist:
|
||||
print "Steinbruckenhoehle is not in the database. Please run parsers.cavetab first."
|
||||
return
|
||||
|
||||
|
||||
def parseSteinbrQMs():
|
||||
try:
|
||||
steinBr=Cave.objects.get(official_name="Steinbrückenhöhle")
|
||||
except Cave.DoesNotExist:
|
||||
print "Steinbruckenhoehle is not in the database. Please run parsers.cavetab first."
|
||||
return
|
||||
|
||||
|
||||
qmPath = settings.EXPOWEB+r"smkridge/204/qm.csv"
|
||||
qmReader = csv.reader(open(qmPath,'r'),dialect="excel-tab")
|
||||
qmPath = settings.EXPOWEB+pathToCSV
|
||||
qmCSVContents = open(qmPath,'r')
|
||||
dialect=csv.Sniffer().sniff(qmCSVContents.read())
|
||||
qmCSVContents.seek(0,0)
|
||||
qmReader = csv.reader(qmCSVContents,dialect=dialect)
|
||||
qmReader.next() # Skip header row
|
||||
for line in qmReader:
|
||||
year=int(line[0][1:5])
|
||||
try:
|
||||
year=int(line[0][1:5])
|
||||
#check if placeholder exists for given year, create it if not
|
||||
if cave=='stein':
|
||||
placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, text="placeholder for QMs in 204", defaults={"date": date(year, 1, 1),"cave":steinBr})
|
||||
elif cave=='hauch':
|
||||
placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, text="placeholder for QMs in 234", defaults={"date": date(year, 1, 1),"cave":hauchHl})
|
||||
if hadToCreate:
|
||||
print cave+" placeholder logbook entry for " + str(year) + " added to database"
|
||||
QMnum=re.match(r".*?-\d*?-X?(?P<numb>\d*)",line[0]).group("numb")
|
||||
newQM = QM()
|
||||
newQM.found_by=placeholder
|
||||
newQM.number=QMnum
|
||||
if line[1]=="Dig":
|
||||
newQM.grade="D"
|
||||
else:
|
||||
newQM.grade=line[1]
|
||||
newQM.area=line[2]
|
||||
newQM.location_description=line[3]
|
||||
newQM.nearest_station_description=line[4]
|
||||
newQM.completion_description=line[5]
|
||||
newQM.comment=line[6]
|
||||
newQM.save()
|
||||
print "QM "+str(newQM) + " added to database"
|
||||
except KeyError:
|
||||
continue
|
||||
# except IndexError:
|
||||
# print "Index error in " + str(line)
|
||||
# continue
|
||||
|
||||
#check if placeholder exists for given year, create it if not
|
||||
placeholder, hadToCreate = LogbookEntry.objects.get_or_create(date__year=year, text="placeholder for QMs in 204", defaults={"date": date(year, 1, 1),"cave":steinBr})
|
||||
if hadToCreate:
|
||||
print "204 placeholder logbook entry for " + str(year) + " added to database"
|
||||
QMnum=re.match(r".*?-\d*?-X?(?P<numb>\d*)",line[0]).group("numb")
|
||||
newQM = QM(found_by=placeholder,number=QMnum,grade=line[1],area=line[2],location_description=line[3],nearest_station_description=line[4],completion_description=line[5],comment=line[6])
|
||||
newQM.save()
|
||||
print "QM "+str(newQM) + " added to database"
|
||||
|
||||
parseSteinbrQMs()
|
||||
parseCaveQMs(cave='stein',pathToCSV=r"smkridge/204/qm.csv")
|
||||
parseCaveQMs(cave='hauch',pathToCSV=r"smkridge/234/qm.csv")
|
||||
|
@ -45,9 +45,36 @@ def LoadPersons():
|
||||
pObject = models.Person(first_name = firstname,
|
||||
last_name = lastname,
|
||||
is_vfho = person[header["VfHO member"]],
|
||||
mug_shot = person[header["Mugshot"]])
|
||||
pObject.save()
|
||||
)
|
||||
|
||||
is_guest = person[header["Guest"]] == "1" # this is really a per-expo catagory; not a permanent state
|
||||
pObject.save()
|
||||
|
||||
#create mugshot Photo instance
|
||||
mugShotPath = settings.EXPOWEB+"folk/"+person[header["Mugshot"]]
|
||||
if mugShotPath[-3:]=='jpg': #if person just has an image, add it
|
||||
mugShotObj = models.Photo(
|
||||
caption="Mugshot for "+firstname+" "+lastname,
|
||||
is_mugshot=True,
|
||||
file=mugShotPath,
|
||||
)
|
||||
mugShotObj.save()
|
||||
mugShotObj.contains_person.add(pObject)
|
||||
mugShotObj.save()
|
||||
elif mugShotPath[-3:]=='htm': #if person has an html page, find the image(s) and add it. Also, add the text from the html page to the "blurb" field in his model instance.
|
||||
personPageOld=open(mugShotPath,'r').read()
|
||||
pObject.blurb=re.search('<body>.*<hr',personPageOld,re.DOTALL).group() #this needs to be refined, take care of the HTML and make sure it doesn't match beyond the blurb
|
||||
for photoFilename in re.findall('i/.*?jpg',personPageOld,re.DOTALL):
|
||||
mugShotPath=settings.EXPOWEB+"folk/"+photoFilename
|
||||
mugShotObj = models.Photo(
|
||||
caption="Mugshot for "+firstname+" "+lastname,
|
||||
is_mugshot=True,
|
||||
file=mugShotPath,
|
||||
)
|
||||
mugShotObj.save()
|
||||
mugShotObj.contains_person.add(pObject)
|
||||
mugShotObj.save()
|
||||
pObject.save()
|
||||
|
||||
for year, attended in zip(headers, person)[5:]:
|
||||
yo = models.Expedition.objects.filter(year = year)[0]
|
||||
|
@ -1,68 +1,60 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/main2.css" />
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/main2.css" />
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
<!-- script to toggle navbar -->
|
||||
|
||||
<script language="javascript">
|
||||
<!--
|
||||
function showFooter(){
|
||||
document.getElementById('footerHidden').style.display = 'none';
|
||||
document.getElementById('footerShowing').style.display = 'block';
|
||||
}
|
||||
|
||||
function hideFooter(){
|
||||
document.getElementById('footerHidden').style.display = 'block';
|
||||
document.getElementById('footerShowing').style.display = 'none';
|
||||
}
|
||||
|
||||
function makeTransparent(){
|
||||
document.getElementById('footerShowing').style.backgroundColor = 'transparent';
|
||||
}
|
||||
-->
|
||||
</script>
|
||||
|
||||
<script src="{{ settings.MEDIA_URL }}js/base.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="editLink" style="right:0px; top:0px; text-align: right; position: absolute; top:0; right:0; z-index:1">
|
||||
{% block editLink %}not editable
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div id="bottomRight" style="position:absolute;right:0;bottom:0">
|
||||
<img src="{{ settings.MEDIA_URL }}SilkRoadsilouetteAndrew.png" id="bridge" style="position:absolute; right:60px; bottom:0;z-index:-1;">
|
||||
{% block lgbkQuote %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="headerBackBar" style="background-color:#CCCC66; position:absolute; left:0; right:0; z-index:-2; top:60px; opacity:0.7; filter:alpha(opacity=70);height:75px; color:#000000; text-indent:100px">
|
||||
<p>
|
||||
<br>
|
||||
{% block currentLocation %}
|
||||
Welcome to the website of the Cambridge University Caving Club's expeditions to Austria.
|
||||
{% endblock %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="contents">
|
||||
<div class="main">
|
||||
{% block content %}{% endblock %}
|
||||
<div class="main"> {% block content %}{% endblock %} </div>
|
||||
{% block footer %}
|
||||
<div class="footer" id="footerHidden">
|
||||
<h4><a href="javascript:;" onMouseDown="showDiv('footerHidden','footerShowing');">[Show Troggle Navigation / Search]</a></h4>
|
||||
</div>
|
||||
{% block footer %}
|
||||
|
||||
<div class="footer" id="footerHidden" style="display:none">
|
||||
<h4><a href="javascript:;" onMouseDown="showFooter();">[Show Troggle Navigation / Search]</a></h4>
|
||||
</div>
|
||||
|
||||
<div class="footer" id="footerShowing" style="background-color:#CCC">
|
||||
<h4 class="navbar"> Troggle navigation <a href="javascript:;" onMouseDown="hideFooter();">[Hide]</a> or <a href="javascript:;" onMouseDown="makeTransparent();">[Make transparent]</a></align></h4>
|
||||
<table class="normal">
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
<a href="{{ settings.URL_ROOT }}cave">list caves</a> or
|
||||
<form name="input" action="{{ settings.URL_ROOT }}cavesearch" method="get">
|
||||
<input type="text" name="q" value="search caves">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
<a href="{{ settings.URL_ROOT }}logbookentry">list logbook entries</a> or
|
||||
<form name="input" action="{{ settings.URL_ROOT }}logbooksearch" method="get">
|
||||
<input type="text" name="q" value="search logbooks">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</td>
|
||||
<td><a href="{{ settings.URL_ROOT }}person">list cavers</a></td>
|
||||
<td><a href="{{ settings.URL_ROOT }}statistics"> statistics</a></td>
|
||||
<tr>
|
||||
<div class="footer" id="footerShowing" style="background-color:#CCC; display:none">
|
||||
<h4 class="navbar"> Troggle navigation <a href="javascript:;" onMouseDown="hideDiv('footerHidden','footerShowing');">[Hide]</a> or <a href="javascript:;" onMouseDown="makeDivTransparent('footerShowing');">[Make transparent]</a>
|
||||
</align>
|
||||
</h4>
|
||||
<table class="normal">
|
||||
<tr>
|
||||
<td rowspan="2"><a href="{{ settings.URL_ROOT }}cave">list caves</a> or
|
||||
<form name="input" action="{{ settings.URL_ROOT }}cavesearch" method="get">
|
||||
<input type="text" name="q" value="search caves">
|
||||
<input type="submit" value="Submit">
|
||||
</form></td>
|
||||
<td rowspan="2"><a href="{{ settings.URL_ROOT }}logbookentry">list logbook entries</a> or
|
||||
<form name="input" action="{{ settings.URL_ROOT }}logbooksearch" method="get">
|
||||
<input type="text" name="q" value="search logbooks">
|
||||
<input type="submit" value="Submit">
|
||||
</form></td>
|
||||
<td><a href="{{ settings.URL_ROOT }}person">list cavers</a></td>
|
||||
<td><a href="{{ settings.URL_ROOT }}statistics"> statistics</a></td>
|
||||
<tr>
|
||||
<td><a href="{{ settings.URL_ROOT }}photos">photos</a></td>
|
||||
<td><a href="{{ settings.URL_ROOT }}admin"> admin</a></td>
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
<p>{% endblock %}</p>
|
||||
</body>
|
||||
<p>{% endblock %}</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -2,7 +2,7 @@
|
||||
{% load wiki_markup %}
|
||||
|
||||
{% block title %}Logbook {{logbookentry.id}}{% endblock %}
|
||||
|
||||
{% block editLink %}<a href="{{settings.URL_ROOT}}admin/expo/logbookentry/{{logbookentry.id}}">edit </a>{% endblock %}
|
||||
{% block content %}
|
||||
<div class="logbookblock">
|
||||
<h2>{{logbookentry.title}} - {{logbookentry.date}}</h2>
|
||||
@ -11,6 +11,7 @@
|
||||
{% for persontrip in logbookentry.persontrip_set.all %}
|
||||
<li>
|
||||
<a href="/person/{{persontrip.personexpedition.person.id}}">{{persontrip.personexpedition}}</a>
|
||||
<a href="{{settings.URL_ROOT}}admin/expo/logbookentry/{{logbookentry.id}}">edit </a>
|
||||
{% ifequal persontrip.personexpedition logbookentry.author %}
|
||||
(author)
|
||||
{% endifequal %}
|
||||
|
Loading…
Reference in New Issue
Block a user