Refactored the model to remove arch and repo tables.

Refactored the model to remove the arch and repo tables. Those data points
are now encapsulated in the package table as an ENUM field.

Changes to models and templates as needed.
This commit is contained in:
eliott 2008-03-22 19:51:01 -07:00
parent 37361f664f
commit 7640082d14
6 changed files with 82 additions and 62 deletions

View File

@ -3,8 +3,8 @@
from django.contrib.auth.models import User
from django.core import validators
from archweb_dev.main.utils import render_response, validate
from archweb_dev.main.models import Package, Repo, Todolist, TodolistPkg
from archweb_dev.main.models import UserProfile, News, Donor, Mirror, Arch
from archweb_dev.main.models import Package, Todolist, TodolistPkg
from archweb_dev.main.models import UserProfile, News, Donor, Mirror
from django.http import HttpResponse
from django.template import Context, loader
@ -35,11 +35,11 @@ def index(request):
})
repo_stats = []
for repo in Repo.objects.all():
for repo in Package.REPOS:
repo_stats.append({
'name': repo.name,
'count': Package.objects.filter(repo__exact = repo).count(),
'flagged': Package.objects.filter(repo__exact = repo).filter(needupdate=True).count()
'name': repo,
'count': Package.objects.filter(repo = Package.REPOS[repo]).count(),
'flagged': Package.objects.filter(Package.REPOS[repo]).filter(needupdate=True).count()
})
return render_response(
@ -89,8 +89,8 @@ def guide(request):
def siteindex(request):
# get the most recent 10 news items
news = News.objects.order_by('-postdate', '-id')[:10]
pkgs = Package.objects.exclude(repo__name__exact='Testing').order_by('-last_update')[:15]
repos = Repo.objects.order_by('name')
pkgs = Package.objects.exclude(repo = Package.REPOS.testing).order_by('-last_update')[:15]
repos = Package.REPOS
return render_response(
request, 'devel/siteindex.html',
{'news_updates': news, 'pkg_updates': pkgs, 'repos': repos})

View File

@ -2,7 +2,34 @@
from django.contrib.auth.models import User
import re
###########################
### Model help classes ###
###########################
class Container(dict):
def __init__(self, dict_entries=None, **entries):
if dict_entries:
self.update(dict_entries)
if entries:
self.update(entries)
def __iter__(self):
rev_items = [(v, k) for k, v in self.items()]
rev_items.sort()
items = [k for v, k in rev_items]
return items.__iter__()
def itertransp(self):
rev_items = [(v, k) for k, v in self.items()]
rev_items.sort()
return rev_items.__iter__()
def __getattr__(self,name):
return self[name]
def __setattr__(self,name,val):
self[name] = val
###########################
### User Profile Class ####
###########################
@ -133,33 +160,19 @@ class Meta:
def get_absolute_url(self):
return '/news/%i/' % self.id
class Arch(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(unique=True,maxlength=255)
class Meta:
db_table = 'archs'
ordering = ['name']
def __str__(self):
return self.name
class Repo(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(maxlength=255)
class Meta:
db_table = 'repos'
ordering = ['name']
def last_update(self):
try:
latest = Package.objects.filter(
repo__name__exact=self.name).order_by('-last_update')[0]
return latest.last_update
except IndexError:
return "N/A"
class Package(models.Model):
## note: purposefully inlining arch and repo.
## they don't change very often (rarely), and it should help compact
## the general model
# architectures
ARCHES = Container(i686=1, x86_64=2)
# repositories
REPOS = Container(core=1, extra=2, testing=3, unstable=4)
id = models.AutoField(primary_key=True)
repo = models.ForeignKey('Repo')
arch = models.ForeignKey('Arch')
## note: the arch and repo elements might need to be indexed. not sure.
repo = models.IntegerField(choices=REPOS.itertransp())
arch = models.IntegerField(choices=ARCHES.itertransp())
maintainer = models.ForeignKey(User, related_name='package_maintainer')
needupdate = models.BooleanField(default=False)
pkgname = models.CharField(maxlength=255)
@ -178,7 +191,8 @@ def get_absolute_url(self):
def required_by_urlize(self):
urls = []
requiredby = PackageDepends.objects.filter(depname=self.pkgname)
requiredby = PackageDepend.objects.filter(
depname=self.pkgname).order_by('depname')
for req in requiredby:
urls.append(
'<li><a href="/packages/%d/">%s</a></li>' % \
@ -187,15 +201,16 @@ def required_by_urlize(self):
def depends_urlize(self):
urls = []
for dep in self.packagedepends_set.all():
for dep in self.packagedepend_set.order_by('depname'):
try:
# we only need depend on same-arch-packages
p = Package.objects.get(
pkgname=dep.depname,
arch=self.arch)
except IndexError:
except Package.DoesNotExist, IndexError:
# couldn't find a package in the DB
# it might be a virtual depend
urls.append('<li>%s (v)</li>' % dep.depname)
urls.append('<li>%s</li>' % dep.depname)
continue
urls.append(
'<li><a href="/packages/%d/">%s</a>%s</li>' % \
@ -207,15 +222,15 @@ class PackageFile(models.Model):
pkg = models.ForeignKey('Package')
path = models.CharField(maxlength=255)
class Meta:
db_table = 'packages_files'
db_table = 'package_files'
class PackageDepends(models.Model):
class PackageDepend(models.Model):
id = models.AutoField(primary_key=True)
pkg = models.ForeignKey('Package')
depname = models.CharField(db_index=True, maxlength=255)
depvcmp = models.CharField(maxlength=255)
class Meta:
db_table = 'packages_depends'
db_table = 'package_depends'
class Todolist(models.Model):
id = models.AutoField(primary_key=True)

View File

@ -7,8 +7,7 @@
from django.contrib.auth.models import User
from datetime import datetime
from archweb_dev.main.utils import validate, render_response
from archweb_dev.main.models import Arch, Repo
from archweb_dev.main.models import Package, PackageFile, PackageDepends
from archweb_dev.main.models import Package, PackageFile, PackageDepend
from django.core.exceptions import ObjectDoesNotExist
@ -38,7 +37,7 @@ def update(request):
def details(request, pkgid=0, name='', repo=''):
if pkgid == 0:
p = Package.objects.filter(pkgname=name)
if repo: p = p.filter(repo__name__exact=repo)
if repo: p = p.filter(repo=Package.REPOS[repo])
# if more then one result, send to the search view
if len(p) > 1: return search(request, name)
if len(p) < 1: return render_response(request, 'error_page.html',
@ -63,11 +62,11 @@ def search(request, query=''):
maint = request.GET.get('maint', 'all')
# build the form lists
repos = Repo.objects.order_by('name')
archs = Arch.objects.order_by('name')
repos = Package.REPOS
arches = Package.ARCHES
# copy GET data over and add the lists
c = request.GET.copy()
c['repos'], c['archs'] = repos, archs
c['repos'], c['arches'] = repos, arches
c['limit'], c['skip'] = limit, skip
c['lastupdate'] = lastupdate
c['sort'] = sort
@ -89,10 +88,18 @@ def search(request, query=''):
results = res1 | res2
else:
results = Package.objects.all()
if repo != 'all': results = results.filter(repo__name__exact=repo)
if arch != 'all': results = results.filter(arch__name__exact=arch)
if maint != 'all': results = results.filter(maintainer=maint)
if lastupdate: results = results.filter(last_update__gte=datetime(int(lastupdate[0:4]),int(lastupdate[5:7]),int(lastupdate[8:10])))
if repo != 'all' and repo in Package.REPOS:
results = results.filter(repo=Package.REPOS[repo])
if arch != 'all' and arch in Package.ARCHES:
results = results.filter(arch=Package.ARCHES[arch])
if maint != 'all':
results = results.filter(maintainer=maint)
if lastupdate:
results = results.filter(
last_update__gte=datetime(
int(lastupdate[0:4]),
int(lastupdate[5:7]),
int(lastupdate[8:10])))
# sort results
if sort == '':

View File

@ -107,8 +107,8 @@ <h3>Package Repositories</h3>
<table id="repolinks">
{% for repo in repos %}
<tr>
<th><a href="/packages/?repo={{ repo.name }}">{{ repo.name }}</a></th>
<td>{{ repo.last_update|date:"Y-m-d H:i" }}</td>
<th><a href="/packages/?repo={{ repo }}">{{ repo }}</a></th>
<td>{{ repo }}</td>
</tr>
{% endfor %}
</table>

View File

@ -33,10 +33,10 @@ <h2 class="title">{{ pkg.pkgname }} {{ pkg.pkgver }}-{{ pkg.pkgrel }}</h2>
<table class="listing">
<tr>
<th>Architecture:</th>
<td>{{ pkg.arch.name }}</td>
<td>{{ pkg.get_arch_display }}</td>
</tr><tr>
<th>Repository:</th>
<td>{{ pkg.repo.name }}</td>
<td>{{ pkg.get_repo_display|capfirst }}</td>
</tr><tr>
<th>Description:</th>
<td>{{ pkg.pkgdesc }}</td>
@ -54,7 +54,7 @@ <h2 class="title">{{ pkg.pkgname }} {{ pkg.pkgver }}-{{ pkg.pkgrel }}</h2>
<br />
<table width="100%">
<tr>
<td valign="top">
<td valign="top" width="50%">
<div class="listing">
<h4>Dependencies:</h4>
<ul style="font-size:small;list-style:none">
@ -62,8 +62,6 @@ <h4>Dependencies:</h4>
</ul>
</div>
</td>
</tr>
<tr>
<td valign="top">
<div class="listing">
<h4>Required By:</h4>

View File

@ -26,15 +26,15 @@ <h4 style="text-align: right">Search Criteria</h4>
<td>
<select name="arch">
<option value="all">All</option>
{% for a in archs %}
<option value="{{ a.arch }}"{% ifequal arch a.name %} selected{% endifequal %}>{{ a.name }}</option>
{% for a in arches %}
<option value="{{ a }}"{% ifequal arch a %} selected{% endifequal %}>{{ a }}</option>
{% endfor %}
</select>
</td><td>
<select name="repo">
<option value="all">All</option>
{% for r in repos %}
<option value="{{ r.name }}"{% ifequal repo r.name %} selected{% endifequal %}>{{ r.name|capfirst }}</option>
<option value="{{ r }}"{% ifequal repo r %} selected{% endifequal %}>{{ r|capfirst }}</option>
{% endfor %}
</select>
</td><td>
@ -87,8 +87,8 @@ <h4 style="text-align: right">Search Criteria</h4>
{% if not user.is_anonymous %}
<td><input type="checkbox" name="pkgid" value="{{ pkg.id }}" /></td>
{% endif %}
<td>{{ pkg.arch.name }}</td>
<td>{{ pkg.repo.name }}</td>
<td>{{ pkg.get_arch_display }}</td>
<td>{{ pkg.get_repo_display|capfirst }}</td>
<td><a href="{{ pkg.get_absolute_url }}">{{ pkg.pkgname }}</a></td>
{% if pkg.needupdate %}
<td><span style="color:red">{{ pkg.pkgver }}-{{ pkg.pkgrel }}</span></td>