I have decided to use Django-Simple-History for building a history of my models. In turn using that to build the dashboard. I have run into a bit of a snag though. I'm trying to output [User] [added,changed, deleted] [object] on/at [time] but I can't figure it out for the life of me.
So far I am able to display the historical record on the template but I can't access anything else, am I missing something?
I was hoping someone with knowledge of Simple History can help, since I couldn't get a hold of the author.
Here is the code snippets I have so far.
Models.py
from simple_history.models import HistoricalRecords
class Project(django.db.models.Model):
...
history = HistoricalRecords()
Views.py
@login_required
def addTMProject(request):
user = request.user
if request.method == 'POST':
form = TimeMaterialsForm(request.POST)
if form.is_valid():
project = form.save(commit=False)
project.created_by = request.user
today = datetime.date.today()
project.pre_quote = "%s-" % (str(today.year)[2:4])
project.quote = Project.objects.latest().quote+1
project.save()
project.history.all()
...
And I have also passed it on my dashboard/views.py so I have access to it.
@login_required
def view_dash(request):
today = datetime.date.today()
user = request.user
proj_perm = user.has_perm('project.add_project')
project = Project.objects.all().order_by('-proj_name')
query = Project.objects.all().order_by('-id')[:5]
que_quotes = Project.objects.filter(status__value__exact = 'Quote')
expired = FollowUp.objects.filter(next_followup__lte=today).order_by('next_followup').filter(archived=False)
log = LogEntry.objects.select_related().all().order_by("-id")
hist = Project.history.all()
return render_to_response('dashboard/home.html', {'user': user, 'project': project, 'query':query, 'que_quotes':que_quotes, 'expired':expired,
'proj_perm':proj_perm, 'log': log, 'hist':hist,}, context_instance=RequestContext(request))
And finally a snippet from my template. As it is right now, the {{ h }} shows "Testing Simple Records as of 2011-04-29 10:43:57" on the template
home.html
{% if user.is_authenticated %}
<div id="large_box">
<h5>Activity</h5>
{% for h in hist %}
<ul>
<li>{{ h }}</li>
</ul>
{% endfor %}
If anyone could help or point me to some more in depth documentation, then that would be great!
Thanks everyone!
Django-Simple-History simply creates a model (and associated database table) that mirrors the object you tie it to and adds four additional fields: history_id
, history_date
, history_type
, and history_object
.
history_id
: standard primary key
history_date
: datetime for when the change occurred
history_type
: one of +
, ~
, -
. (+
means added, ~
means changed, and -
means deleted)
history_object
: representation of the model that history is being stored for
So, at most basic level, you can roughly get "[added,changed, deleted] [object] on/at [time]" in your output, using something to the effect of:
{{ h.history_type }} {{ h.history_object }} on/at {{ h.history_date }}
You'll probably want to create template tag or something to convert the +
, ~
, and -
to the more understandable, 'Created', 'Changed', 'Deleted'. {{ h.history_object }}
should return the object's __unicode__
, I'm assuming, so you might need to make some modifications there or return something like {{ h.history_object.__class__ }}
or {{ h.history_object._meta.verbose_name }}
, instead. (Not sure if those will actually work in practice though.) And, of course, you can apply the date
filter to {{ h.history_date }}
to make it any format you want.
Getting the user is more difficult. Django-Simple-History doesn't seem to store this data, so there's no record of what user made the modification. However, since it basically duplicates the object as it existed, you could probably get away with adding a modified_by
field to your model and filling that with request.user
pre-save. Then, when Django-Simple-History does its thing, that field would be copied over like the rest and be available via {{ h.modified_by }}
.
I'm assuming that the only problem you're having is with the displaying of the historical data and not the actual saving portion of it.
I'm not sure what fields you have in your Project model, but it looks like the history field is treated like a foreign key field. This foreign key's table contains the same fields that your Project model does. So, if you want to access the fields you'd have to do something like this in your template:
...
{% for h in hist %}
<ul>
<li>{{h.field1}} {{h.field2}} {{h.field3}} on {{h.field4}}</li>
</ul>
{% endfor %}
...
I found this page (http://qr7.com/2010/10/django-simple-history-ftw/) which was quite helpful, but you'll have to play around with the history field names. I wasn't quite sure what they actually were.
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With