Reputation: 13
I have an affiliate program app with redirects and link statistics tracking. A read-only field in the Django Admin should display the full URL of the affiliate link, (so the user can copy+paste this into their editor) but the reverse()
call in the model instance's get_absolute_url()
method is failing when called from a callable in the admin class. For example:
urlpatterns = patterns(
'',
url(r'^a/', include('shop.affiliates.urls', namespace='affiliates')),
...
urlpatterns = patterns(
'',
url(r'^(?P<slug>[\w]+)/$', redirect_to_affiliate_link, name='affiliate_redirect'),
)
class AffiliateLink(models.Model):
...
slug = models.SlugField(
max_length=4,
help_text='The slug for this link, used to generate url.',
)
...
def get_absolute_url(self):
return reverse(
'affiliates:affiliate_redirect',
kwargs={'slug': self.slug},
)
Note: for the sake of debugging simplicity, it's safe to assume that the slug
field has already been populated in the database previously. So I'm not trying to create a new object where slug
has not yet been set.
class AffiliateLinkInline(admin.StackedInline):
model = AffiliateLink
extra = 0
fields = (
..., 'hyperlink', ...
)
readonly_fields = (
'hyperlink', ...
)
def hyperlink(self, obj):
url = 'http://example.com{}'.format(obj.get_absolute_url())
return '<a href="{0}">{0}</a>'.format(url)
hyperlink.allow_tags = True
When loading the appropriate admin page, I get a NoReverseMatch
exception.
Exception value:
Reverse for 'affiliate_redirect' with arguments '()' and keyword arguments '{u'slug': u''}' not found. 1 pattern(s) tried: [u'a/(?P<slug>[\\w]+)/$']
so the proper regex is found, but the slug parameter is empty. I verified that obj.slug
within the admin callable exists, and it is the correct AffiliateLink
slug. To make matters more strange, if I switch the kwargs in get_absolute_url()
like so:
def get_absolute_url(self):
return reverse(
'affiliates:affiliate_redirect',
kwargs={'bug': self.slug},
)
Then the exception value changes to:
Reverse for 'affiliate_redirect' with arguments '()' and keyword arguments '{u'bug': u'7aeB'}' not found. 1 pattern(s) tried: [u'a/(?P<slug>[\\w]+)/$']
So the kwarg value for key 'slug' disappears from the exception value, but the value for 'bug' stays.
What am I doing wrong here? Any help is greatly appreciated.
Upvotes: 1
Views: 235
Reputation: 6005
URL patterns are sometime evaluated before URLconf has been loaded. Try reverse_lazy
instead of reverse
https://docs.djangoproject.com/en/dev/ref/urlresolvers/#reverse-lazy
Upvotes: 1