Question

I am new to django and I am using django-taggit 0.10a1 for tagging functionality in my django 1.4.2 application. I also tried django-tagging app but as that project was not maintained and as django-taggit had a lot of positive reviews from developers, I opted for that.

I was wondering if the any of you can help me with the problem I am seeing. After following the documentation, I added :

tags = TaggableManager()

to all my models that need tagging. Most of the models automatically added Tags section in the django admin as the documentation specified, but for some of the models, Tags section doesn't show up on admin UI. I was not able to figure out why. Here are a couple of models that I have with the tags line declared after all the fields. If you see anything wrong in the placement of that statement in my model, and if you can let me know if you see any issue, I would greatly appreciate it. Sample non-working models with TaggableManager are as follows:


DigitalObject model

class DigitalObject(models.Model):
    title = models.CharField(max_length=255, verbose_name=_("title"))
    ascii_title = models.CharField(max_length=255, verbose_name=_("ASCII title"))
    title_variants = models.CharField(max_length=300, null=True, blank=True, verbose_name=_("title variants"))
    collection = models.ForeignKey(Collection, related_name="collection_objects", verbose_name=_("collection"))
    object_creator = models.ForeignKey(Creator, null=True, blank=True, related_name="objects_created", verbose_name=_("object creator"))
    language = models.ManyToManyField("Language", null=True, blank=True, verbose_name=_("language"), related_name="language_objects")
    subject = models.ManyToManyField(SubjectHeading, null=True, blank=True, related_name="collection_objects", verbose_name=_("subject"))
    object_id = models.CharField(max_length=6, null=True, blank=True, verbose_name=_("object ID"))
    digital_id = models.CharField(max_length=100, null=True, blank=True, verbose_name=_("digital ID"))
    rights_holders = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("rights holder(s)"))
    license_type = models.ForeignKey("License", default=1, verbose_name=_("license type"))
    permission_form = models.FileField(upload_to='permissionforms', verbose_name=_("permission form"), null=True, blank=True)
    # Physical object info
    identifier = models.CharField(max_length=60, help_text=_("e.g. ISBN, ISSN, DOI"), null=True, blank=True, verbose_name=_("identifier"))
    marks = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("marks/inscriptions"))
    measurements = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("physical description"))
    phys_object_type = models.ForeignKey("PhysicalObjectType", verbose_name=_("Physical object type"), related_name="digital_objects", null=True, blank=True)
    donor = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("donor"))
    sponsor_note = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("sponsor note"))
    phys_obj_date = models.DateField(null=True, blank=True, verbose_name=_("physical object date"))
    phys_obj_precision = models.CharField(max_length=1, choices=constants.DATE_PRECISION_CHOICES, default=u'f', null=True, blank=True, verbose_name=_("Precision"))
    phys_obj_BC = models.BooleanField(default=False, verbose_name=_("Is B.C. date"))
    phys_obj_location = models.ForeignKey("Location", null=True, blank=True, verbose_name=_("physical object location"))
    # Digital object info
    digi_object_format = models.ForeignKey("DigitalObjectType", verbose_name=_("Digital object format"), null=True, blank=True)
    # Container info
    series_num = models.CharField(max_length=12, null=True, blank=True, verbose_name=_("series #"))
    series_name = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("series name"))
    subseries_num = models.CharField(max_length=12, null=True, blank=True, verbose_name=_("subseries #"))
    subseries_name = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("subseries name"))
    box_num = models.CharField(max_length=12, null=True, blank=True, verbose_name=_("box #"))
    folder_num = models.CharField(max_length=12, null=True, blank=True, verbose_name=_("folder #"))
    drawer_num = models.CharField(max_length=12, null=True, blank=True, verbose_name=_("drawer #"))
    folder_name = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("folder name"))
    folder_date = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("folder date"))
    # Relationships
    related_production = models.ManyToManyField(Production, related_name="related_objects", null=True, blank=True, verbose_name=_("related production"))
    related_festival = models.ManyToManyField(FestivalOccurrence, related_name="related_objects", null=True, blank=True, verbose_name=_("related festival"))
    related_venue = models.ManyToManyField(Location, related_name="related_objects", null=True, blank=True, verbose_name=_("related venue"))
    related_creator = models.ManyToManyField(Creator, related_name="related_objects", null=True, blank=True, verbose_name=_("related creator"))
    related_work = models.ManyToManyField(WorkRecord, related_name="related_objects", null=True, blank=True, verbose_name=_("related work"))
    # extra details
    summary = models.TextField(null=True, blank=True, verbose_name=_("summary"))
    notes = models.TextField(null=True, blank=True, verbose_name=_("notes"))
    creation_date = models.DateField(null=True, blank=True, help_text="Click 'Today' to see today's date in the proper date format.", verbose_name=_("creation date"))
    creation_date_precision = models.CharField(max_length=1, null=True, blank=True, choices=constants.DATE_PRECISION_CHOICES, default=u'y', verbose_name=_("Precision"))
    creation_date_BC = models.BooleanField(default=False, verbose_name=_("Is B.C. date"))
    restricted = models.BooleanField(default=False, verbose_name=_("Restricted?"))
    restricted_description = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("Details of restrictions"))
    ready_to_stream = models.BooleanField(default=False, verbose_name=_("Uploaded to streaming server"))
    hi_def_video = models.BooleanField(default=False, verbose_name=_("Hi-def video"))
    poster_image = models.FileField(upload_to='digitalobjects/poster_images', storage=OverwriteStorage(), verbose_name=_("Poster image (for videos)"), null=True, blank=True)
    attention = models.TextField(null=True, blank=True, verbose_name=_("attention"))
    has_attention = models.BooleanField(default=False)
    needs_editing = models.BooleanField(default=True, verbose_name=_("needs editing"))
    published = models.BooleanField(default=True, verbose_name=_("published"))   
    tags = TaggableManager()

    def phys_obj_date_display(self):
        return display_date(self.phys_obj_date, self.phys_obj_precision, self.phys_obj_BC)

    def creation_date_display(self):
        return display_date(self.creation_date, self.creation_date_precision, self.creation_date_BC)

    def has_related_things(self):
        if self.related_production.exists():
            return True
        if self.related_festival.exists():
            return True
        if self.related_venue.exists():
            return True
        if self.related_creator.exists():
            return True
        if self.related_work.exists():
            return True
        return False

    def object_number(self):
        num = ''
        num += self.collection.repository.repository_id
        num += self.collection.collection_id
        num += self.object_id
        return num

    def first_file(self):
        if self.files:
          df = self.files.order_by('seq_id')[0]
          return df
        else:
          return False

    def __unicode__(self):
        return "%s (%s)" % (self.title, str(self.object_number()))

def update_digital_object_title(sender, **kwargs):
    obj = kwargs['instance']
    obj.ascii_title = unidecode(obj.title)

pre_save.connect(update_digital_object_title, sender=DigitalObject)

WorkRecord model

class WorkRecord(models.Model):
    title = models.CharField(max_length=255, verbose_name=_("title"))
    title_variants = models.CharField(max_length=300, null=True, blank=True, verbose_name=_("title variants"))
    ascii_title = models.CharField(max_length=255, verbose_name=_("ASCII title"))
    creators = models.ManyToManyField(Creator, through="WorkRecordCreator", verbose_name=_("creators"))
    creators_display = models.CharField(max_length=255, verbose_name=_("creators"))
    work_type = models.ForeignKey("WorkRecordType", verbose_name=_("work type"))
    subject = models.ManyToManyField(SubjectHeading, null=True, blank=True, related_name="works", verbose_name=_("subject"))
    genre = models.ForeignKey("WorkGenre", null=True, blank=True, help_text=_("The work's genre - e.g. drama, comedy"), verbose_name=_("genre"))
    culture = models.ForeignKey("WorkCulture", null=True, blank=True, help_text=_("The culture the work is a part of"), verbose_name=_("culture"))
    style = models.ForeignKey("WorkStyle", null=True, blank=True, help_text=_("A movement or period the work belongs to"), verbose_name=_("style"))
    lang = models.ManyToManyField("Language", null=True, blank=True, verbose_name=_("language"))
    creation_date = models.DateField(null=True, blank=True, help_text="Click 'Today' to see today's date in the proper date format.", verbose_name=_("creation date"))
    creation_date_precision = models.CharField(max_length=1, choices=constants.DATE_PRECISION_CHOICES, default=u'y', null=True, blank=True, verbose_name=_("Precision"))
    creation_date_BC = models.BooleanField(default=False, verbose_name=_("Is B.C. date"))
    publication_date = models.DateField(null=True, blank=True, help_text="Click 'Today' to see today's date in the proper date format.", verbose_name=_("publication date"))
    publication_date_precision = models.CharField(max_length=1, choices=constants.DATE_PRECISION_CHOICES, default=u'y', null=True, blank=True, verbose_name=_("Precision"))
    publication_date_BC = models.BooleanField(default=False, verbose_name=_("Is B.C. date"))
    publication_rights = models.CharField(max_length=30, null=True, blank=True, verbose_name=_("publication rights"))
    performance_rights = models.CharField(max_length=30, null=True, blank=True, verbose_name=_("performance rights"))
    website = models.URLField(null=True, blank=True, help_text=_("A site where users can find the text of this work"), verbose_name=_("website"))
    digital_copy = models.ForeignKey("DigitalObject", null=True, blank=True, verbose_name=_("digital copy"))
    summary = models.TextField(null=True, blank=True, verbose_name=_("summary"))
    notes = models.TextField(null=True, blank=True, verbose_name=_("notes"))
    related_works = models.ManyToManyField("self", through="RelatedWork", symmetrical=False, null=True, blank=True, related_name="related_to", verbose_name=_("related works"))
    attention = models.TextField(null=True, blank=True, verbose_name=_("attention"))
    has_attention = models.BooleanField(default=False)
    needs_editing = models.BooleanField(default=True, verbose_name=_("needs editing"))
    published = models.BooleanField(default=True, verbose_name=_("published"))
    awards_text = models.TextField(null=True, blank=True, verbose_name=_("awards (plain text)"))
    biblio_text = models.TextField(null=True, blank=True, verbose_name=_("bibliography (plain text)"))
    biblio_text_es = models.TextField(null=True, blank=True, verbose_name=_("bibliography (plain text, Spanish)"))
    secondary_biblio_text = models.TextField(null=True, blank=True, verbose_name=_("secondary bibliography (plain text)"))
    secondary_biblio_text_es = models.TextField(null=True, blank=True, verbose_name=_("secondary bibliography (plain text, Spanish)"))
    tags = TaggableManager()

    def creation_date_display(self):
        return display_date(self.creation_date, self.creation_date_precision, self.creation_date_BC)
    creation_date_display.short_description = _("Creation date")

    def publication_date_display(self):
        return display_date(self.publication_date, self.publication_date_precision, self.publication_date_BC)
    publication_date_display.short_description = _("Publication date")

    def creators_display_links(self):
        cs = ""
        for wrc in WorkRecordCreator.objects.filter(work_record=self):
            cs += "<a href='/creator/" + str(wrc.creator.id) + "'>"
            cs += wrc.creator.display_name()
            cs += "</a>, "
        cs = cs.rstrip(', ')
        return cs

    def has_system_links(self):
        if AwardCandidate.objects.filter(work_record=self).exists():
            return True
        elif RelatedWork.objects.filter(first_work=self).exists():
            return True
        elif RelatedWork.objects.filter(second_work=self).exists():
            return True
        elif WorkRecordCreator.objects.filter(work_record=self).exists():
            return True
        elif Role.objects.filter(source_text=self).exists():
            return True
        elif Production.objects.filter(source_work=self).exists():
            return True
        elif DigitalObject.objects.filter(related_work=self).exists():
            return True
        elif BibliographicRecord.objects.filter(work_record=self).exists():
            return True
        else:
            return False

    def __unicode__(self):
        return "%s (%s)" % (self.title, self.work_type.name)

def update_wr_title(sender, **kwargs):
    obj = kwargs['instance']
    obj.ascii_title = unidecode(obj.title)

pre_save.connect(update_wr_title, sender=WorkRecord)

I would sincerely appreciate if any of you could please take a look at it and let me know if you see anything that I might have missed or if you need more information to understand my issue.

Thanks in advance.

Was it helpful?

Solution

Turns out that the models for which the tags column wasn't appearing had field sets in admin.py. For models which are not arranged by field sets, taggit automatically adds "tags" column to Admin UI. For the ones which are arranged by fieldsets, "tags" column from model should be specifically included in one of the the field sets.

admin.py for WorkRecord model

class WorkRecordAdmin(TranslationAdmin):
    form = arcforms.WorkRecordAdminForm
    inlines = (WorkRecordCreatorInline, RoleInline, RelatedWorkInline,)
    list_display = ('title', 'creators_display', 'work_type', 'genre', 'culture', 'style', 'has_system_links')
    list_filter = ('work_type', 'lang', 'genre', 'culture', 'style', 'has_attention',)
    search_fields = ['title', 'ascii_title', 'title_variants']
    filter_horizontal = ['subject', 'lang']
    fieldsets = (
        ('Titles', {
            'fields': ('title', 'title_variants')
        }),
        ('Description', {
            'fields': ('work_type', 'subject', 'genre', 'culture', 'style', 'lang')
        }),
        ('Creation / Publication', {
            'fields': (('creation_date', 'creation_date_precision', 'creation_date_BC'), ('publication_date', 'publication_date_precision', 'publication_date_BC'), 'publication_rights', 'performance_rights')
        }),
        ('Access', {
            'fields': ('website', 'digital_copy')
        }),
        ('Standard fields', {
            'fields': ('summary', 'notes', 'attention', 'needs_editing', 'published', 'tags')
        })
    )

tags column is included in the Standard fields fieldset above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top