Login

Links with XFN (and Validation)

Author:
Turophile
Posted:
December 28, 2008
Language:
Python
Version:
1.0
Tags:
xfn microformats
Score:
0 (after 0 ratings)

Slightly different validation to that of jpwatts; developed with knowledge of that snippet but written up from scratch for use as a fallback for when the Javascript Assist is off.

I'm no master programmer, so feedback/comments/criticism is more than welcome.

The accompanying Javascript (xfn-admin.js) can be found here: http://www.djangosnippets.org/snippets/1266/.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
#########################################################################################
# mysite/general/admin.py
#########################################################################################

from django.contrib import admin
from django import forms
from mysite.general.models import Link, LinkCategory

class XFNForm(forms.ModelForm):
    error = {
        'me': u'You cannot have a relationship with yourself.  ',
        'fr': u'You can only be one type of friend.  ',
        'geo': u'You can only have one geographical relationship.  ',
        'fa': u'I certainly hope you are only related in one way...  ',
    }

    def clean_rel(self):
        error = str(); out = str()
        rel_types = {
          'fr': ('contact','acquaintance','friend'),
          'met': ('met',),
          'pro': ('co-worker','colleague'),
          'geo': ('co-resident', 'neighbor'),
          'fa': ('child','parent','sibling','spouse','kin'),
          'ro': ('muse','crush','date','sweetheart')
        }

        rel_limit = {'fr': 1,'met': 1,'geo': 1,'fa': 1}


        data = str(self.cleaned_data['rel']).lower()
        relations = rel_types.keys()

        """ Highlight Duplicates """
        for type in relations:
            for manner in rel_types[type]:
                if data.count(manner) >= 2:
                   error += 'You have duplicate entries for '+str(manner)+'. '
                else:
                    if data.count(manner):
                        out += manner+' '
                        if type in rel_limit:
                            rel_limit[type] -= 1
                            if rel_limit[type] < 0:
                               error += self.error[type]

        if out.count('me') and out.count('met') == 0 and len(out.strip(' ')) >= 3:
           error += self.error['me']

        if error:
            raise forms.ValidationError(error)
        else:
            return out[:-1]

class LinkAdmin(admin.ModelAdmin):
    form = XFNForm
    list_display = ('name','category')
    fieldsets = (
        ('Link', {
            'fields': ('name','url'),
        }),
        ('Display Method', {
            'fields': ('category','display_type'),
        }),
        ('XFN', {
            'fields': ('rel',),
        }),
    )
    radio_fields = {'category': admin.HORIZONTAL, 'display_type': admin.HORIZONTAL}
    class Media:
        js = ("/src/admin/js/xfn-admin.js",)

# Making the Category a radio field seems strange, so you don't have to do it; it's a personal preference.


class LinkCategoryAdmin(admin.ModelAdmin):
    list_display = ('display_name',)

admin.site.register(Link, LinkAdmin)


#########################################################################################
# mysite/general/models.py
#########################################################################################

from django.db import models

LINK_DISPLAY = (
  ('blog_roll', 'Blog Roll'),
  ('bot_links', 'Bottom Link List'),
  # Add whatever you want here or even make another LinkCategory type thing :)
  # These are taken straight from my layout so I can pull them by tag.
)

class LinkCategory(models.Model):
    display_name = models.CharField(max_length=125)
    def __unicode__(self):
        return self.display_name
    class Meta:
        verbose_name = "Link Category"
        verbose_name_plural = "Link Categories"


class Link(models.Model):
    name = models.CharField(max_length=100)
    url = models.URLField(verify_exists=True, max_length=500)
    rel = models.CharField("XFN Relation", max_length=82, blank=True, null=True)
    category = models.ForeignKey(LinkCategory)
    display_type = models.CharField(max_length=50, choices=LINK_DISPLAY, default=None, blank=True, null=True)
    def __unicode__(self):
        return self.name

More like this

Comments

Please login first before commenting.