예제 #1
0
class PostWithEmbeddedObject(BasicPost):
    '''Post that can display embedded objects, e.g. Youtube.
    '''
    detail_post_embedded_html = EnhancedTextField(blank=True, default="\H")
    list_post_embedded_html = EnhancedTextField(blank=True, default="\H")

    class Meta:
        verbose_name = _('post with embedded object')
        verbose_name_plural = _('posts with embedded objects')
예제 #2
0
파일: models.py 프로젝트: ng/tbonline
class Catalogue(models.Model):
    title = models.CharField(max_length=200)
    description = EnhancedTextField(blank=True, default="\W")
    documents = models.ManyToManyField(Document, blank=True, null=True,
                help_text=_('Documents in this archive.'))
    tags = generic.GenericRelation(TaggedItem, verbose_name=_('tags'), 
                                      blank=True, null=True)
    copyright = models.ForeignKey(Copyright, blank=True, null=True)
    last_modified = models.DateTimeField(auto_now=True, editable=False)
    date_added = models.DateTimeField(auto_now_add=True, editable=False)

    def describe(self):
        return self.description

    @models.permalink
    def get_absolute_url(self):
        return ('calalogue_view', [str(self.id)])
    
    def __unicode__(self):
        return self.title
    
    class Meta:
        verbose_name = _('catalogue')
        verbose_name_plural = _('catalogues')
        ordering = ['title',]
예제 #3
0
class Drug(models.Model):
    name = models.CharField(max_length=200, unique=True)
    synopsis = EnhancedTextField(blank=True, default="\W")
    formula = models.CharField(max_length=200, blank=True)
    chemical_photo = models.ForeignKey(Image, blank=True, null=True)
    studies = models.ManyToManyField(Study)
    side_effects = models.ManyToManyField(SideEffect)
예제 #4
0
class Condition(models.Model):
    name = models.CharField(max_length=200)
    description = EnhancedTextField(blank=True, default="\W")

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = [
            'name',
        ]
예제 #5
0
class Category(models.Model):
    '''Represents a category for other objects. Designed with posts in mind.
    '''
    name = models.CharField(max_length=50)
    description = EnhancedTextField(blank=True, default="\W")

    def __unicode__(self):
        return self.name

    class Meta:
        verbose_name = _('category')
        verbose_name_plural = _('categories')
예제 #6
0
class Gallery(models.Model):
    title = models.CharField(max_length=200)
    description = EnhancedTextField(blank=True, default="\W")
    tags = generic.GenericRelation(TaggedItem, verbose_name=_('tags'), 
                                      blank=True, null=True)
    images = models.ManyToManyField(Image, blank=True, null=True, through="OrderedImage")
    copyright = models.ForeignKey(Copyright, blank=True, null=True)
    last_modified = models.DateTimeField(auto_now=True, editable=False)
    date_added = models.DateTimeField(auto_now_add=True, editable=False)

    def describe(self):
        return self.description
    
    def get_images(self):
        return self.images.order_by('orderedimage__position')
    
    def __unicode__(self):
        return self.title
    
    class Meta:
        verbose_name = _('gallery')
        verbose_name_plural = _('galleries')
        ordering = ['-last_modified',]
예제 #7
0
파일: models.py 프로젝트: ng/tbonline
class Webpage(models.Model):
    """Represents manually maintained links to external web pages for display,
    say, on the front page of a website.
    """
    title = models.CharField(max_length=200)
    url = models.CharField(max_length=200, verbose_name=_('URL'))
    byline = models.CharField(blank=True,
                              max_length=200,
                              help_text=_(
                                  'The institution or organisation '
                                  'that produces this website. There is no '
                                  'problem with leaving this blank.'))
    date = models.DateField(blank=True,
                            null=True,
                            help_text=_(
                                'Sometimes it is useful to include the '
                                'date a blog was written. But mostly this '
                                'field will be left blank.'))
    html_A_tag_options = models.CharField(
        max_length=200,
        blank=True,
        help_text=_('You can put link, title and other '
                    'HTML A tag attributes here. '
                    'Leave blank if you are unsure.'))
    description = EnhancedTextField(blank=True, default="\W")
    date_last_edited = models.DateTimeField(auto_now=True, editable=False)

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = [
            'date_last_edited',
        ]
        verbose_name = _('webpage')
        verbose_name_plural = _('webpages')
예제 #8
0
파일: models.py 프로젝트: ng/tbonline
class Document(models.Model):
    title = models.CharField(max_length=200)
    file = FileBrowseField(max_length=200, directory="documents/", blank=True, null=True)
    url = models.URLField(blank=True,
            verify_exists=False,
            verbose_name='External URL',
            help_text= _('Use this field as an alternative to uploading a file'))
    content = EnhancedTextField(blank=True,
            help_text = _('Use this field as an alternative to uploading a file or specifying a URL.'),
            default=("\W")) 
    description = EnhancedTextField(blank=True,
            help_text = _('Describe the document.'),
            default=("\W"))
    
    source = models.CharField(max_length=200, blank=True)
    publisher = models.CharField(max_length=200, blank=True)
    
    year_published = models.PositiveSmallIntegerField(blank=True, null=True)
    month_published = models.CharField(blank=True, max_length=2, choices=MONTH_CHOICES)
    day_published = models.PositiveSmallIntegerField(blank=True, null=True)
    
    recommended_citation = models.CharField(max_length=300, blank=True,
            help_text=_("Leave blank for system to automatically generate a citation."))
    citation_format = models.CharField(max_length=3, choices=CITATION_FORMATS,
                                       default='DEF')
    
    pmid = models.IntegerField(blank=True, null=True,
            help_text=_("Enter a Public Library of Medicine identifier if there is one."))
    doi = models.CharField(max_length=50, blank=True,
            help_text=_("Enter a Digital Object Identifier if there is one. E.g. 10.1021/ac0354342"))    
    credits = generic.GenericRelation(OrderedCredit, verbose_name=_('credit',), 
                                      blank=True, null=True) 
    copyright = models.ForeignKey(Copyright, blank=True, null=True)
    tags = generic.GenericRelation(TaggedItem, verbose_name=_('tags'), 
                                      blank=True, null=True) 
    last_modified = models.DateTimeField(auto_now=True, editable=False)
    date_added = models.DateTimeField(auto_now_add=True, editable=False)

    def describe(self):
        return self.description
    
    def get_count_authors(self):
        return credit_length(self.credits)
    
    def get_authors(self):
        return credit_list(self.credits)
    
    def get_date_published(self):
        if not self.year_published:
            return ""
    
            
        date_published= unicode(abs(self.year_published)) 
        
        if self.month_published:
            date_published += u' ' + self.get_month_published_display()      
        
            if self.day_published:
                date_published += u' ' + unicode(self.day_published) 

        return date_published


    
    def get_citation(self):
        """Generates a citation for the document. 
        
        Currently only default citation is implemented.
        """
        if self.recommended_citation:
            return self.recommended_citation
        
        citation = ""
        
        if self.citation_format == 'DEF':
            
            # Authors, title, date, source, PMID, DOI, URL
            authors = self.get_authors()
            if authors:
                citation += self.get_authors() + u'. '
                
            citation += self.title + u'. '
             
            date_published = self.get_date_published()
            
            if date_published:
                citation += date_published + u'. '
                
            if self.source:
                citation += self.source + u'. '
            if self.publisher:
                citation += self.publisher + u'. '
    
            if self.pmid:
                citation += 'PMID: ' + unicode(self.pmid) + '. '
                
            if self.doi:
                citation += 'DOI:' + self.doi + '. '
    
            if self.url: 
                citation += self.url + u'. '
            elif self.file: 
                citation += "http://" + unicode(Site.objects.get_current()) + unicode(self.file)
            else:
                citation += "http://" + unicode(Site.objects.get_current()) + self.get_absolute_url()

        return citation
             
    def clean(self):
        '''Validates the year/month/day combination is valid. Users can omit all 
        three, but if they enter a month, they must enter a year and if they 
        enter a day, they must enter a month.  
        '''
        
        # Don't allow draft entries to have a pub_date.
        if self.year_published: 
            year = self.year_published             
            if self.month_published:
                month = int(self.month_published)
            elif self.day_published:
                raise ValidationError(_('You must enter a month if you enter a day'))
            else:
                month = 1 # For purposes of validating the year
            if self.day_published:
                day = self.day_published
            else:
                day = 1 # For purposes of validating the year/month combination
            try:
                datetime.date(year,month,day)
            except (TypeError, ValueError):
                raise ValidationError(_('The date is invalid')) 
        elif self.month_published or self.day_published:
            raise ValidationError(_('You must enter a year if you enter a month or day'))        
                          
    @models.permalink
    def get_absolute_url(self):
        return ('document-detail', [str(self.id)])
    
    def __unicode__(self):
        return self.title

    class Meta:
        verbose_name = _('document')
        verbose_name_plural = _('documents')
        ordering = ['-year_published','-month_published', '-day_published']
예제 #9
0
class BasicPost(models.Model):
    '''This is the standard post. Complex post types requiring more 
    sophisticated content should inherit from this one. 
    
    This is really the most important class in the system. Most of the system's
    functionality is built around this model.
    '''

    title = models.CharField(max_length=200,
                             help_text=_(
                                 "The article title should be short, no more "
                                 "than seven words. It should convey the "
                                 "article's essence."))
    subtitle = models.CharField(
        max_length=200,
        blank=True,
        help_text=_("The subtitles should also be short but it can "
                    "be a bit longer than the title. "
                    "Only use a subtitle if it adds useful "
                    "information about the content or will draw "
                    "readers to the article. Otherwise leave "
                    "blank."))
    authors = generic.GenericRelation(OrderedCredit,
                                      verbose_name=_('authors'),
                                      blank=True,
                                      null=True)
    teaser = EnhancedTextField(blank=True,
                               help_text=_('For display on multi-post pages.'),
                               default=("\W"))
    introduction = EnhancedTextField(
        blank=True,
        help_text=_('Displayed on detail post page separately from the body'),
        default=("\W"))
    body = EnhancedTextField(
        blank=True,
        default=("\W"),
        help_text=_('This is the content of the article.<br>'
                    'Note: Instead of filling in the <em>teaser</em> '
                    'and <em>introduction</em> fields, you can use '
                    '&#60;!--endteaser--&#62; and/or '
                    '&#60;!--endintro--&#62; in this field to indicate '
                    'where the teaser and/or introduction end '
                    'respectively.'))

    pullout_text = models.CharField(
        max_length=400,
        blank=True,
        help_text=_('Usually used for a nice quote that will '
                    'be prominently displayed'))
    slug = models.SlugField(
        help_text=_('Used in the URL to identify the post. '
                    'This field is usually filled in '
                    'automatically by the system. The '
                    'system will ensure it has a  unique '
                    'value.<br/>'
                    '<b>Warning:</b> If you change the '
                    'slug after a post is published '
                    'the link to the post will change '
                    'and people who have bookmarked the '
                    'old link will not find it.'))
    homepage = models.BooleanField(
        default=True,
        help_text=_('Check to display this post on the home page'))
    sticky = models.BooleanField(
        default=False,
        help_text=_('Check to display at top of home page even when newer '
                    'posts are published.'))
    category = models.ForeignKey(
        Category,
        blank=True,
        null=True,
        help_text=_('Assign this post to a category. '
                    'Posts can only have one category, but multiple tags'))

    date_published = models.DateTimeField(
        blank=True,
        null=True,
        help_text=_('A post is published if the publication date has '
                    'passed. Leave blank while this is a draft.<br/>'
                    '<b>Warning:</b> If you change this '
                    'date after a post is published '
                    'the link to the post will change '
                    'and people who have bookmarked the '
                    'old link will not find it.'))
    last_modified = models.DateTimeField(auto_now=True, editable=False)
    date_added = models.DateTimeField(auto_now_add=True, editable=False)

    allow_comments = models.BooleanField(default=True)

    detail_post_template = models.CharField(
        max_length=200,
        blank=True,
        help_text=_('Use this field to indicate an alternate html template '
                    'for detail post pages. It is safe to leave this blank.'))
    list_post_template = models.CharField(
        max_length=200,
        blank=True,
        help_text=_('Use this field to indicate an alternate html template '
                    'for list post pages. It is safe to leave this blank.'))
    detail_post_css_classes = models.CharField(
        max_length=200,
        blank=True,
        help_text=_('Use this field to indicate additional css classes for '
                    'detail post pages. Separate classes with a space. It is '
                    'safe to leave this blank.'))
    list_post_css_classes = models.CharField(
        max_length=200,
        blank=True,
        help_text=_('Use this field to indicate additional css classes for '
                    'list post pages. Separate classes with a space. '
                    'It is safe to leave this blank.'))

    copyright = models.ForeignKey(Copyright, blank=True, null=True)
    sites = models.ManyToManyField(Site)
    tags = generic.GenericRelation(TaggedItem,
                                   verbose_name=_('tags'),
                                   blank=True,
                                   null=True)
    objects = PostManager()

    def __get_template__(self, template_name, list_or_detail):
        '''Determines the template name for rendering a post and returns it as 
        a string.  
        
        The default template name is the class name + list_or_detail + html 
        extension.  
        '''
        if template_name:
            return template_name
        else:
            import os
            return os.path.join(
                self._meta.app_label,
                self.__class__.__name__.lower() + list_or_detail + '.html')

    def get_post_list_template(self):
        '''Determines the post list template name and returns it as a string.
        
        A list post template renders a bunch of posts on a webpage.  
        '''
        return self.__get_template__(self.list_post_template, '_list_snippet')

    def get_post_detail_template(self):
        '''Determines the post detail template name and returns it as a string.
        
        A detail post template renders one post on a webpage.  
        '''
        return self.__get_template__(self.detail_post_template,
                                     '_detail_snippet')

    def get_authors(self):
        '''Uses the credit_list utility function to generate a list of authors
        as a printable string.
        '''
        return credit_list(self.authors)

    def get_teaser_intro_body(self):
        '''Calculates the teaser, intro and body for this post
        
        The following possibilities exist:
        Key - 0: Field not set
              t: teaser field set
              i: intro field set
              x: teaser tag set
              y: intro tag set
              
              01. 0000: No fields set - return first paragraph as intro and 
                        teaser, remainder as body
              02. t000: teaser field set - return teaser and intro as teaser, 
                        full body as body
              03. ti00: Simplest case - teaser and intro fields set. Return 
                        full body as body  
              04. tix0: Both teaser field and tag set. Teaser field overrides 
                        teaser tag.  
              05. ti0y: Both intro field and intro tag set. Intro field 
                        overrides intro tag    
              06. 0i00: Intro field set. Teaser set to intro. Body to remainder. 
              07. 0ix0: Intro field and teaser tag set. (Madness!) Body set to 
                        remainder. 
              08. 0ixy: Same as above, but intro field overrides intro tag.
              09. 00x0: Teaser tag test. Set intro to teaser and body to 
                        remainder.
              10. 00xy: Teaser and intro tags set. Body to remainder
              11. 000y: Intro tag set. Set teaser to intro and body to 
                        remainder. 
              
        '''

        # Simplest case - they've all been set by the user

        teaser = unicode(self.teaser)
        intro = unicode(self.introduction)
        body = unicode(self.body)

        if not teaser:
            # Next simplest case: They've all been set in the body using tags
            contents = body.partition('<!--endteaser-->')

            if contents[1]:  # The <!--endteaser--> tag is used
                teaser = contents[0]
                body = contents[2]  # Body comes from remainder of text

                if not intro:  # Intro field not set
                    contents = body.partition('<!--endintro-->')

                    if contents[1]:  # The <!--endintro--> tag has been used
                        intro = contents[0]
                        body = contents[2]  # Body is remainder of text
                    else:  # <!--endintro--> tag not used, so set intro to teaser
                        intro = teaser

            else:  # <!--endteaser--> tag not used
                if intro:  # intro field has been set
                    teaser = intro
                else:  # intro field has not been set - look for <!--endintro-->
                    contents = body.partition('<!--endintro-->')

                    if contents[1]:  # <!--endintro--> tag used
                        teaser = intro = contents[0]
                        body = contents[2]  # body is remainder of text
                    else:  # No intro or teaser field set and no tags - get 1st para
                        contents = body.partition('</p>')

                        if not contents[1]:  # Maybe it's a capital P?
                            contents = body.partition('</P>')

                        if not contents[1]:  # No paragraphs!
                            teaser = intro = contents[0]
                            body = ""
                        else:
                            teaser = intro = contents[0] + contents[1]
                            body = contents[2]

        else:  # The teaser exists

            if not intro:  # But the intro doesn't
                contents = body.partition('<!--endintro-->')

                if contents[1]:  # <!--endintro--> tag used
                    intro = contents[0]
                    body = contents[2]
                else:  # <!--endintro--> tag not used
                    intro = teaser
                    body = contents[0]

        return (teaser, intro, body)

    def get_teaser(self):
        return self.get_teaser_intro_body()[0]

    def get_introduction(self):
        return self.get_teaser_intro_body()[1]

    def get_body(self):
        return self.get_teaser_intro_body()[2]

    def describe(self):
        '''Describe methods are used by several apps in the system to return a
        description of themselves. 
        
        Some templates depend on this method existing to produce sensible
        output.   
        '''
        return self.get_introduction()

    def is_published(self):
        '''A post is published if the date-time is > date_published. 
        
        This method together with the Object Manager's published() method
        violates DRY to some extent. It is critical that they stay logically in
        sync.
        '''
        try:
            if datetime.datetime.now() >= self.date_published:
                return True
            else:
                return False
        except:
            return False

    is_published.short_description = _("published")
    is_published.boolean = True

    @staticmethod
    def get_subclasses():
        '''Determines all the subclasses of BasicPost, even new user defined 
        ones. 
        '''
        return [
            rel for rel in BasicPost._meta.get_all_related_objects()
            if isinstance(rel.field, models.OneToOneField)
            and issubclass(rel.field.model, BasicPost)
        ]

    def get_class(self):
        '''Will return the type of self unless this is a BasicPost in which case 
        it will try to see if there's a subclass and return that. 
        
        If that fails. return BasicPost.
        '''
        if isinstance(self, BasicPost):
            for cls in BasicPost.get_subclasses():
                try:
                    inst = getattr(self, cls.var_name)
                    if inst:
                        return type(inst)
                except ObjectDoesNotExist:
                    pass
            return BasicPost
        else:
            return type(self)

    def get_class_name(self):
        return self.get_class().__name__

    def describe_for_admin(self):
        '''Returns a string description of the type of this Post for the admin
        interface.
        '''
        return self.get_class()._meta.verbose_name

    describe_for_admin.short_description = "Type"
    describe_for_admin.allow_tags = True

    @models.permalink
    def get_admin_url(self):
        '''Ensures that if the user clicks on a Post in the admin interface,
        the correct change screen is opened for this type of Post. 
        
        For example, if the Post is a PostWithImage, then the PostWithImage
        admin change screen must open, not the BasicPost change screen. 
        '''
        cls = self.get_class()
        return ('admin:post_' + self.get_class().__name__.lower() + '_change',
                [str(self.pk)])

    def render_admin_url(self):
        '''Called from the Admin interface to generates the html to link a post
        to its correct change screen. 
        
        Works in conjunction with get_admin_url() 
        '''
        return u'<a href="'+ self.get_admin_url() + u'">'+ unicode(self.pk) + \
                u'</a>'

    render_admin_url.short_description = _('ID')
    render_admin_url.allow_tags = True
    render_admin_url.admin_order_field = 'id'

    @staticmethod
    def get_posts_by_tags_union(tags):
        '''Returns all posts which contain any of the tags in the list of tags
        passed as an argument to this method.
        '''

        if type(tags) == str or type(tags) == unicode:
            tags = tags.rsplit(",")

        if type(tags) != list:
            raise TypeError("Tags is a %s. Expected tags to be a list, string"
                            " or unicode object." % unicode(type(tags)))

        posts = []

        for t in tags:
            try:
                tag = Tag.objects.get(name=t)
            except Tag.DoesNotExist:
                continue

            posts_for_this_tag = list(TaggedItem.objects.\
                                      get_by_model(BasicPost, tag))
            for cls in BasicPost.get_subclasses():
                posts_for_this_tag += list(TaggedItem.objects.\
                                           get_by_model(cls.model, tag))


            posts += filter(lambda p: p.is_published() and \
                Site.objects.get_current() in p.sites.all(), posts_for_this_tag)

        return list(set(posts))  # Remove duplicates

    @staticmethod
    def get_posts_by_tags_intersection(tags):
        '''Returns all posts that have all the tags in the list of tags passed
        in the argument to this method. 
        '''

        if type(tags) == str or type(tags) == unicode:
            tags = tags.rsplit(",")
        if type(tags) != list:
            raise TypeError("Tags is a %s. Expected tags to be a list, string"
                            " or unicode object." % unicode(type(tags)))

        posts = set([])
        for i, t in enumerate(tags):
            try:
                tag = Tag.objects.get(name=t)
            except Tag.DoesNotExist:
                continue

            posts_for_this_tag = list(TaggedItem.objects.\
                                      get_by_model(BasicPost, tag))
            for cls in BasicPost.get_subclasses():
                posts_for_this_tag += list(TaggedItem.objects.\
                                           get_by_model(cls.model, tag))

            posts_for_this_tag = set(filter(lambda p: p.is_published() and \
                        Site.objects.get_current() in \
                            p.sites.all(), posts_for_this_tag))

            if i > 0:
                posts = posts & posts_for_this_tag
            else:
                posts = posts_for_this_tag

        return list(posts)

    def _get_unique_slug(self):
        '''Makes slug unique, if it is not already, and returns it as a string.
        '''
        slug_unique = False
        counter = 1
        slug = self.slug

        while not slug_unique:
            if self.pk:
                posts = BasicPost.objects.filter(slug=slug).\
                    exclude(pk=self.pk)
            else:
                posts = BasicPost.objects.filter(slug=slug)
            if len(posts) == 0:
                slug_unique = True
            else:
                slug = self.slug + "-" + unicode(counter)
                counter += 1
        return slug

    def save(self, *args, **kwargs):
        # Make the slug unique
        self.slug = self._get_unique_slug()
        super(BasicPost, self).save(*args, **kwargs)

    @staticmethod
    def get_posts_by_categories(categories):
        '''Returns all posts which are in the given categories.
        
        Note category is a foreign key, so a post only belongs to one category. 
        Therefore there is no union or intersection operation as there is 
        for tags.  
        '''
        if type(categories) == str or type(categories) == unicode:
            categories = categories.rsplit(",")
        if type(categories) != list:
            raise TypeError("Categories is a %s. Expected tags to be a list, "
                            "string or unicode object." %
                            unicode(type(categories)))

        return BasicPost.objects.published().\
                    filter(category__name__in=categories).\
                        select_subclasses().distinct()

    @staticmethod
    def get_posts_by_author(author):
        '''Returns all posts which is authored or co-authored by the author
        passed as an argument to this method.
        '''
        if type(author) == str or type(author) == unicode:
            author = int(author)

        if type(author) != int:
            raise TypeError(
                "Author is a %s. Expected author to be an int, string"
                " or unicode object." % unicode(type(author)))

        author = Credit.objects.get(id=author)
        ordered_credits = OrderedCredit.objects.filter(credit=author)
        posts = []
        post_classes = [BasicPost]
        for subclass in BasicPost.get_subclasses():
            post_classes.append(subclass.model)
        for ordered_credit in ordered_credits:
            if type(ordered_credit.content_object) in post_classes:
                if ordered_credit.content_object.is_published():
                    posts.append(ordered_credit.content_object)
        posts = set(posts)
        return posts

    @models.permalink
    def get_absolute_url(self):
        if self.is_published():
            return ('post_detail', [
                str(self.date_published.year),
                str(self.date_published.month),
                str(self.date_published.day),
                str(self.slug)
            ])
        else:
            return ('post_draft_detail', [str(self.id)])

    def __unicode__(self):
        return self.title

    class Meta:
        verbose_name = _('post')
        verbose_name_plural = _('posts')
        ordering = ['-sticky', '-date_published']
        unique_together = ('slug', 'date_published')
예제 #10
0
class Story(models.Model):
    '''Story model encapsulates a collection of ordered posts.
    Useful for representing a book or connected articles that need a table of
    contents.
    '''

    title = models.CharField(max_length=200)
    slug = models.SlugField()
    description = EnhancedTextField(blank=True, default="\W")
    posts = models.ManyToManyField(BasicPost,
                                   through='OrderedPost',
                                   blank=True,
                                   null=True)
    authors = generic.GenericRelation(OrderedCredit,
                                      verbose_name=_('authors'),
                                      blank=True,
                                      null=True)

    date_published = models.DateTimeField(
        blank=True,
        null=True,
        help_text=_('Leave blank while this is a draft.'))
    last_modified = models.DateTimeField(auto_now=True, editable=False)
    date_added = models.DateTimeField(auto_now_add=True, editable=False)
    tags = generic.GenericRelation(TaggedItem,
                                   verbose_name=_('tags'),
                                   blank=True,
                                   null=True)

    def is_published(self):
        try:
            if datetime.datetime.now() >= self.date_published:
                return True
            else:
                return False
        except:
            return False

    is_published.short_description = _("published")

    def get_posts(self):
        posts = [
            orderedpost.post for orderedpost in self.orderedpost_set.all()
            if orderedpost.post.is_published()
        ]
        return posts

    def describe(self):
        return self.description

    @models.permalink
    def get_absolute_url(self):
        if self.is_published():
            return ('story_detail', [
                str(self.date_published.year),
                str(self.date_published.month),
                str(self.date_published.day), self.slug
            ])
        else:
            return (
                'draft_story',
                [str(self.id)],
            )

    def __unicode__(self):
        return self.title

    class Meta:
        verbose_name = _('story')
        verbose_name_plural = _('stories')
        ordering = ['-date_published']
예제 #11
0
class Image(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    file = FileBrowseField(max_length=200, directory="images/", format='image', 
                           blank=True, null=True)
    preferred_size = models.CharField(max_length=1, choices=SIZES,
                        blank=True,
                        help_text=_('In some cases setting this can help HTML '
                                    'writers display the image display.'))
    caption = models.CharField(max_length=200, blank=True)
    url = models.URLField(blank=True, verify_exists=False,
                verbose_name=('URL'),
                help_text=_('URL for image to link to, usually the source.'))
    description = EnhancedTextField(blank=True, default="\W")
    credits = generic.GenericRelation(OrderedCredit, verbose_name=_('Credit',), 
                                      blank=True, null=True)
    copyright = models.ForeignKey(Copyright, blank=True, null=True)
    tags = generic.GenericRelation(TaggedItem, verbose_name=_('tags'), 
                                      blank=True, null=True) 
    last_modified = models.DateTimeField(auto_now=True, editable=False)
    date_added = models.DateTimeField(auto_now_add=True, editable=False)
             
    def image_thumbnail(self):
        if self.file and self.file.filetype == "Image":
            return '<img src="%s" />' % self.file.url_thumbnail
        else:        
            return ""

    image_thumbnail.allow_tags = True
    image_thumbnail.short_description = "Thumbnail"

    def _get_unique_slug(self):
        '''Makes slug unique, if it is not already, and returns it as a string.
        '''
        slug_unique = False
        counter = 1
        slug = self.slug
        
        while not slug_unique: 
            if self.id:
                images = Image.objects.filter(slug=slug).\
                    exclude(pk=self.id)
            else:                
                images = Image.objects.filter(slug=slug)
            if len(images) == 0:
                slug_unique = True
            else:
                slug = self.slug + "-" + unicode(counter)
                counter += 1
        return slug
        
    def get_credits(self):
        return credit_list(self.credits)

    def describe(self):
        if unicode(self.description).strip():
            return self.description
        else:
            return self.caption

    @models.permalink
    def get_absolute_url(self):
        return ('image_view', [str(self.id)])

    def __unicode__(self):
        return self.title
    
    class Meta:
        verbose_name = _('image')
        verbose_name_plural = _('images')
        ordering = ['-last_modified']