zta1987
zta1987

Reputation: 167

Dynamically generated xml file in Django

I would like to dynamically generate an xml file for recent events, so I can parse the file later. I tried to use django, serializing Django objects, and some other ways, but I was never successful in doing so.

#views.py

from django.utils.translation import ugettext as _
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from events.models import Event, Attendance
from events.forms import EventForm
from dateutil.parser import parse
from django.core import serializers
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.views.decorators.http import require_POST
from django.core.urlresolvers import reverse
from django.core import serializers


def recentEvents(request, everyone=True):

    """
    Renders a list of ``Event`` instances, which are selected mainly based on
    two factors:

    The ``everyone`` parameter:
    If this is set to False, then we filter down the event list to be only
    those events that were created by or attended by one of the people who
    the user follows.
    If the user is authenticated, the user's events are separated from the
    other events.
    """
events = Event.objects.today().filter(latest=True)
if request.user.is_authenticated():
    my_events = events.filter(creator=request.user) |      events.filter(attendance__user=request.user)
    events = events.exclude(creator=request.user).exclude(attendance__user=request.user)
    following = request.user.following_set.all().values_list('to_user', flat=True)
else:
    my_events = Event.objects.none()
    following = None

if not everyone:
    events = events.filter(creator__in=following) |     events.filter(attendance__user__in=following)
events = events.order_by('-start_date', '-creation_date').distinct()
context = {
    'events': events,
    'my_events': my_events,
    'following': following,
    'event_form': EventForm(),
}
return render_to_response('events/recentEvents.html',
    context,
    context_instance = RequestContext(request)
)

def oldEvents(request, everyone=True):

"""
Renders a list of ``Event`` instances, which are selected mainly based on
one parameter:

``everyone``:
    If this is set to False, then we filter down the event list to be only
    those events that were created by or attended by one of the people who
    the user follows.
"""

events = Event.objects.filter(latest=False) | Event.objects.filter(attendance__user__isnull=False)
if request.user.is_authenticated():
    following = list(request.user.following_set.all().values_list('to_user', flat=True))
else:
    following = None
if not everyone:
    following.append(request.user.id)
    events = events.filter(creator__in=following) | events.filter(attendance__user__in=following)
events = events.order_by('-creation_date', '-start_date').distinct()
context = {
    'events': events,
    'following': following,
}
return render_to_response('events/oldEvents.html',
    context,
    context_instance = RequestContext(request)
)

def event(request, id):
    """
    Render a single event.
    """
    event = get_object_or_404(Event, id=id)
    return render_to_response('events/event_details.html',
        {'event': event},
        context_instance = RequestContext(request)
    )

def create(request):
    """
    Renders a form for creating a new ``Event`` instance, validates against that
    form, and creates the new instances.
    """
    form = EventForm(request.POST or None)
    if form.is_valid():
        event = form.save(commit=False)
        event.creator = request.user
        guessed_date = None

        for word in event.description.split():
        try:
            guessed_date = parse(word)
            break
        except ValueError:
            continue
        event.start_date = guessed_date
    event.save()
    if 'next' in request.POST:
        next = request.POST['next']
else:
        next = reverse('recentEvents')
    if request.is_ajax():
        # If the request is AJAX, then render the created event and don't
        # create messages for the user.
        try:
            Attendance.objects.get(event=event, user=request.user)
            attending = True
        except Attendance.DoesNotExist:
            attending = False
        return render_to_response('events/event.html', {'event': event,
            'request': request, 'attending': attending,
            'authenticated': True, 'event_num': 1, 'next': next})

  else:
        # If the request is not AJAX, then create messages for the user and
        # redirect them to the next page.
        request.user.message_set.create(
            message=_('Your event was posted.'))
        return HttpResponseRedirect(next)
if request.is_ajax():
    raise Http404
return render_to_response(
    'events/create.html',
    {'form': form},
    context_instance = RequestContext(request)
)
create = login_required(create)

def toggle_attendance(request):
    """
    Toggles whether a user is set to attend an event or not.
    """
    try:
        event_id = int(request.POST['event_id'])
    except (KeyError, ValueError):
        raise Http404
event = get_object_or_404(Event, id=event_id)
attendance, created = Attendance.objects.get_or_create(user=request.user, event=event)
if not created:
    attendance.delete()
if request.is_ajax():
    # If the request is AJAX, return JSON representing the new count of
    # people who are attending the event.
    json = '{"created": %s, "count": %s}' % (created and 'true' or 'false',
        event.attendees.all().count())
    return HttpResponse(json, mimetype='application/json')
# If the request was not AJAX, create messages for the user.
if created:
    request.user.message_set.create(
        message=_('You are now attending "%s"') % unicode(event))
else:
    request.user.message_set.create(
        message=_('You are no longer attending "%s"') % unicode(event))
next = request.POST.get('next', '')
#if not next:
#    next = reverse('ev_tonight')

return HttpResponseRedirect(next)
toggle_attendance = require_POST(login_required(toggle_attendance))



#generate xml file
def xml_latest(request):
    if request.is_ajax():
        #format = 'xml'
        mimetype = 'application/xml'

        #return serializers.serialize("xml", Event.objects.all())

        data = serializers.serialize("xml", Event.objects.all())
        #out = open("file.xml", "w")
        #xml_serializer.serialize(Event.objects.all(), stream=out)
        return HttpResponse(data,mimetype)
     else:
        return HttpResponse(status=400)

models.py

from datetime import datetime, timedelta
from django.db import models
from django.contrib.auth.models import User
from django.db.models.query import QuerySet

def today():
"""
Returns a tuple of two datetime instances: the beginning of today, and the
end of today.
"""
now = datetime.now()
start = datetime.min.replace(year=now.year, month=now.month,
    day=now.day)
end = (start + timedelta(days=1)) - timedelta.resolution
return (start, end)

class EventQuerySet(QuerySet):
"""
A very simple ``QuerySet`` subclass which adds only one extra method,
``today``, which returns only those objects whose ``creation_date`` falls
within the bounds of today.
"""
def today(self):
    """
    Filters down to only those objects whose ``creation_date`` falls within
    the bounds of today.
    """
    return self.filter(creation_date__range=today())

class EventManager(models.Manager):
"""
A very simple ``Manager`` subclass which returns an ``EventQuerySet``
instead of the typical ``QuerySet``.  It also includes a proxy for the extra
``today`` method that is provided by the ``EventQuerySet`` subclass.
"""
def get_query_set(self):
    """
   return EventQuerySet(self.model)

def today(self):
    """
    A proxy method for the extra ``today`` method that is provided by the
    ``EventQuerySet`` subclass.
    """
    return self.get_query_set().today()

class Event(models.Model):
description = models.TextField()
start_date = models.DateTimeField(null=True, blank=True)
creation_date = models.DateTimeField(default=datetime.now)
creator = models.ForeignKey(User, related_name='event_creator_set')
attendees = models.ManyToManyField(User, through='Attendance')
latest = models.BooleanField(default=True)

objects = EventManager()

def __unicode__(self):
    """
    Returns the first 80 characters of the description, or less, if the
    description is less than 80 characters.
    """
    if len(self.description) > 80:
        return self.description[:76] + ' ...'
    return self.description[:80]

def save(self, **kwargs):
    """
    First this updates all events created today by the same creator as this
    event, and sets their ``latest`` field to False.

    Then, this simply saves the object.  Since the default for ``latest`` is
    to be set to True, it will be passed through and saved as the latest
    event for today by this user.
    """
    Event.objects.today().filter(creator=self.creator).update(latest=False)
    super(Event, self).save(**kwargs)

def today(self):
    """
    Determines whether this event takes place today or not.
    """
    (start, end) = today()
    return self.creation_date >= start and self.creation_date <= end

def description_size(self):
    """
    Useful only for display purposes, this designates a label of 'small',
    'medium', or 'large' to the description text size.
    """
    if len(self.description) < 120:
        return 'small'
    elif len(self.description) < 240:
        return 'medium'
    else:
        return 'large'

class Attendance(models.Model):
"""
This is the explicit intermediary model mapping ``User`` instances to
``Event`` instances.
"""
user = models.ForeignKey(User)
event = models.ForeignKey(Event)
registration_date = models.DateTimeField(default=datetime.now)

def __unicode__(self):
    return "%s is attending %s" % (self.user.username, self.event)

Can anyone help please!!! Thanks in advance

Upvotes: 0

Views: 3250

Answers (1)

John Mee
John Mee

Reputation: 52283

XML is no different to HTML so perhaps the quickest way for most is to create a template, just like an html template, and render to it. Something like

 return TemplateResponse(request, 'events.xml', {'events': Event.objects.all()})

If json is an acceptable alternative to xml, and you're feeling more technical, I like to extend the jsonencoder and dump that into the response.

Upvotes: 2

Related Questions