Sunday, July 26, 2015

URL Generation

Hello all,

I have an issue that I've been trying to work around in a generic fashion (so that I'm not repeating myself in views/templates). Let's say I have three models:

# models
class Organization(models.Model):
    name = models.CharField(max_length=250, null=False, blank=False, unique=True)


class Team(models.Model):
    organization = models.ForeignKey(Organization, null=False)
    name = models.CharField(max_length=250)


class Competition(models.Model):
    organization = models.ForeignKey(Organization, null=False)
    name = models.CharField(max_length=250)
    teams = models.ManyToManyField(Team, related_name='competitions')


And this basic URL structure:

# urls

# organization URL's
url(
    regex=r'organization/',
    view=include(organization_urlpatterns, namespace='organization'),
),

# team URL's
url(
    regex=r'organization/(?P<organization_pk>\d+)/team/',
    view=include('project.teams.urls', namespace='team'),
),

# competition URL's
url(
    regex=r'organization/(?P<organization_pk>\d+)/competition/',
    view=include('project.competitions.urls', namespace='competition'),
),


# competition team listing - project.competitions.urls
url(
    regex=r'^(?P<competition_pk>\d+)/team/',
    view=include('project.teams.urls', namespace='team'),
),


In this (simplified version of my) application, a Team is a member of an Organization. Competitions are created within the Organization, and will have one or more Teams associated with them. Teams can be associated with multiple Competitions, but not with multiple Organizations.

Focusing on Teams specifically, there are two URL's/views that can be used to view a Team. One from the perspective of an Organizatoin (where you can see all of the teams associated with an Organization), and one within the context of a Competition, where you can see a list of Teams filtered specifically for that Competition.

Here's my dilemma. I need to generate various links to get to other parts of the application, but if the user is working within the 'context' of a competition (adding/removing teams, etc.), then I need the links for objects to be relative to the Competition that they are working on. For example, a link to 'list all teams' in the Organization context should list all of the teams within an Organization, but should be limited to the associated teams in a Competition context (using the term context generally, not referring to a template context). 

Normally I would use something like get_absolute_url() on the model, but the model object has no concept of the 'context' of where/how it is being modified, so get_absolute_url() would unconditionally return the URL as if it were being viewed at an Organizational level, meaning that all of the links would take the user out of the context where they were expecting, and force them to navigate back into it.

I have several other models that need to follow a similar URL scheme, so something generic would be appreciated.

I have a sneaking suspicion that utilizing app_name within the URL's could be beneficial, but I can't seem to grasp the concept of how to properly use an app_name with URL's, and have it apply to my situation (I'm already using instance namepaces, which have been working out peachy so far). It'd be nice to just have 'team:create' as the namespace and have Django automagically determine whether or not it should stay within the Comeptition context. The other wrinkle in this is that any operations performed in the Competition context currently require an extra kwarg (competition_pk) to specify what Competition is in use, whereas both URL's are already aware of the Organization (organization_pk). I'm open to reworking the URL structure if someone can point me in the right direction and that is the only hurdle.

What URL resolution strategies would be appropriate in this situation? 

Thank you in advance,

-James

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CA%2Be%2BciUQtquvkdYa3JHe_8QxpSfrH9AnkmrR9d8siJCjd-hZtA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment