Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django History for Custom Dashboard

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!

like image 448
TheLifeOfSteve Avatar asked Apr 29 '11 15:04

TheLifeOfSteve


Video Answer


2 Answers

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 }}.

like image 94
Chris Pratt Avatar answered Sep 24 '22 05:09

Chris Pratt


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.

like image 37
Bryce Siedschlaw Avatar answered Sep 20 '22 05:09

Bryce Siedschlaw