Mercurial > public > sg101
view downloads/models.py @ 943:cf9918328c64
Haystack tweaks for Django 1.7.7.
I had to upgrade to Haystack 2.3.1 to get it to work with Django
1.7.7. I also had to update the Xapian backend. But I ran into
problems.
On my laptop anyway (Ubuntu 14.0.4), xapian gets mad when search terms
are greater than 245 chars (or something) when indexing. So I created
a custom field that would simply omit terms greater than 64 chars and
used this field everywhere I previously used a CharField.
Secondly, the custom search form was broken now. Something changed in
the Xapian backend and exact searches stopped working. Fortunately the
auto_query (which I was using originally and broke during an upgrade)
started working again. So I cut the search form back over to doing an
auto_query. I kept the form the same (3 fields) because I didn't want
to change the form and I think it's better that way.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Wed, 13 May 2015 20:25:07 -0500 |
parents | 3e1905e523be |
children | a5ebc74dc3f3 |
line wrap: on
line source
""" Models for the downloads application. """ import os import datetime from django.db import models from django.contrib.auth.models import User from django.template.defaultfilters import filesizeformat from core.markup import site_markup class Category(models.Model): """Downloads belong to categories.""" title = models.CharField(max_length=64) slug = models.SlugField(max_length=64) description = models.TextField(blank=True) count = models.IntegerField(default=0, blank=True) class Meta: verbose_name_plural = 'Categories' ordering = ('title', ) def __unicode__(self): return self.title def download_path(instance, filename): """ Creates a path for a download. Uses the current date to avoid filename clashes. Uses the current microsecond also to make the directory name harder to guess. """ now = datetime.datetime.now() parts = ['downloads'] parts.extend([str(p) for p in (now.year, now.month, now.day)]) parts.append(hex((now.hour * 3600 + now.minute * 60 + now.second) * 1000 + ( now.microsecond / 1000))[2:]) parts.append(filename) return os.path.join(*parts) class PublicDownloadManager(models.Manager): """The manager for all public downloads.""" def get_queryset(self): return super(PublicDownloadManager, self).get_queryset().filter( is_public=True).select_related() class DownloadBase(models.Model): """Abstract model to collect common download fields.""" title = models.CharField(max_length=128) category = models.ForeignKey(Category) description = models.TextField() html = models.TextField(blank=True) file = models.FileField(upload_to=download_path) user = models.ForeignKey(User) date_added = models.DateTimeField(db_index=True) ip_address = models.IPAddressField('IP Address') update_date = models.DateTimeField(db_index=True, blank=True) class Meta: abstract = True def size(self): try: return filesizeformat(self.file.size) except OSError: return '?' class PendingDownload(DownloadBase): """This model represents pending downloads created by users. These pending downloads must be approved by an admin before they turn into "real" Downloads and are visible on site. """ class Meta: ordering = ('date_added', ) def __unicode__(self): return self.title def save(self, *args, **kwargs): if not self.pk: self.date_added = datetime.datetime.now() self.update_date = self.date_added else: self.update_date = datetime.datetime.now() self.html = site_markup(self.description) super(PendingDownload, self).save(*args, **kwargs) class Download(DownloadBase): """Model to represent a download.""" hits = models.IntegerField(default=0) average_score = models.FloatField(default=0.0) total_votes = models.IntegerField(default=0) is_public = models.BooleanField(default=False, db_index=True) # Managers: objects = models.Manager() public_objects = PublicDownloadManager() def __unicode__(self): return self.title @models.permalink def get_absolute_url(self): return ('downloads-details', [str(self.id)]) def save(self, *args, **kwargs): if not self.pk: self.date_added = datetime.datetime.now() self.update_date = self.date_added else: self.update_date = datetime.datetime.now() self.html = site_markup(self.description) super(Download, self).save(*args, **kwargs) def vote(self, vote_value): """receives a vote_value and updates internal score accordingly""" total_score = self.average_score * self.total_votes total_score += vote_value self.total_votes += 1 self.average_score = total_score / self.total_votes return self.average_score def search_title(self): return self.title def search_summary(self): return self.description class AllowedExtensionManager(models.Manager): def get_extension_list(self): return self.values_list('extension', flat=True) class AllowedExtension(models.Model): """Model to represent the list of allowed file extensions.""" extension = models.CharField(max_length=8, help_text="e.g. .txt") objects = AllowedExtensionManager() def __unicode__(self): return self.extension class Meta: ordering = ('extension', ) class VoteRecord(models.Model): """Model to record the date that a user voted on a download.""" download = models.ForeignKey(Download) user = models.ForeignKey(User) vote_date = models.DateTimeField(auto_now_add=True) def __unicode__(self): return u"%s voted on '%s' on %s" % ( self.user.username, self.download.title, self.vote_date.strftime('%b %d, %Y %H:%M:%S')) class Meta: ordering = ('-vote_date', )