Browse Source

Get rid of PartCategory, start working with tags

master
Dashie der otter 3 years ago
parent
commit
8c0dfc8a5c

+ 1
- 1
controllers/ajax_categories.py View File

@@ -1,6 +1,6 @@
from flask import Blueprint, json, request, jsonify
from flask.ext.security import login_required
from models import db, PartCategory
from models import db, Tag

bp_ajax_categories = Blueprint('bp_ajax_categories', __name__)


+ 1
- 1
controllers/ajax_parts.py View File

@@ -1,6 +1,6 @@
from flask import Blueprint, render_template, jsonify, request, current_app
from flask.ext.security import login_required
from models import db, Part, PartCategory, PartParameter,\
from models import db, Part, Tag, PartParameter,\
Unit, PartManufacturer, PartDistributor, PartAttachment
from utils import path_or_none
import os

+ 1
- 1
controllers/autocompletes.py View File

@@ -1,6 +1,6 @@
from flask import Blueprint, render_template, jsonify, request, current_app, json, Response
from flask.ext.security import login_required
from models import db, Part, PartCategory, PartParameter,\
from models import db, Part, Tag, PartParameter,\
Unit, PartManufacturer, PartDistributor, PartAttachment
from utils import path_or_none
import os

+ 1
- 1
controllers/parts.py View File

@@ -4,7 +4,7 @@ from flask import Blueprint, render_template, url_for, request,\
jsonify, redirect, current_app, send_from_directory
from flask.ext.security import login_required, current_user

from models import db, Part, PartCategory, Unit, Distributor, Manufacturer, PartAttachment, BARCODE_TYPES
from models import db, Part, Tag, Unit, Distributor, Manufacturer, PartAttachment, BARCODE_TYPES
from forms import PartForm, PartAttachmentForm
import os


+ 1
- 1
controllers/views.py View File

@@ -1,6 +1,6 @@
from flask import Blueprint, render_template, request, Response
from flask.ext.security import login_required
from models import StorageCategory, Part, PartCategory, PartAttachment, PartParameter
from models import StorageCategory, Part, Tag, PartAttachment, PartParameter
from sys import version as python_version
import texttable


+ 1
- 52
dbseed.py View File

@@ -1,4 +1,4 @@
from models import user_datastore, PartCategory, FootprintCategory, Manufacturer, \
from models import user_datastore, Tag, FootprintCategory, Manufacturer, \
PartMeasurementUnit, Footprint, Unit, ManufacturerLogo

from flask import current_app
@@ -16,8 +16,6 @@ import os
def make_db_seed(db):
print("== Seeding database")
seed_users(db)
seed_root_categories(db)
seed_categories(db)
seed_manufacturers(db)
seed_manufacturers_logos(db)
seed_parts_units(db)
@@ -93,55 +91,6 @@ def seed_units(db):
db.session.commit()


def seed_root_categories(db):
print("++ Seeding root categories")
a = PartCategory()
a.parent_id = None
a.name = "Root"
a.description = "Root category"

db.session.add(a)
db.session.commit()

b = PartCategory(parent_id=a.id, name="# Uncategorized")
db.session.add(b)
db.session.commit()


def seed_categories(db):
print("++ Seeding categories")
a = db.session.query(PartCategory).filter(PartCategory.name == 'Root', PartCategory.id == 1).one()
if not a:
print('Can\'t find root category \'Root\' with null parent...')
return

with open('setup-data/categories.json', 'r') as stream:
cats = json.load(stream)

if not cats:
print("Cats null, is the file correct or not empty filled with json ?")
return

categories = cats['response']

def walk_tree(child, parent_id):
print(u"> {0} - {1}".format(parent_id, child['name']))
# Here we have a category
_c = PartCategory(parent_id=parent_id,
name=child['name'],
description=child['description'])
db.session.add(_c)
db.session.commit()
# Walking through childs if any
if 'children' in child:
for ci in child['children']:
walk_tree(ci, _c.id)

# We don't want to manage the Root category as we already create them it first
for i in categories['children']:
walk_tree(i, a.id)


def seed_manufacturers_logos(db):
print("++ Seeding manufacturers logos")
with open('setup-data/manufacturers/manufacturers.yaml', 'r') as stream:

+ 56
- 0
migrations/versions/2396a54ec576_.py View File

@@ -0,0 +1,56 @@
"""Get rid of PartCategory

Revision ID: 2396a54ec576
Revises: 2e1affad10af
Create Date: 2016-02-03 20:58:29.876950

"""

# revision identifiers, used by Alembic.
revision = '2396a54ec576'
down_revision = '2e1affad10af'

from alembic import op
import sqlalchemy as sa


def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('tag',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=100), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('tags',
sa.Column('tag_id', sa.Integer(), nullable=True),
sa.Column('part_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['part_id'], ['part.id'], ),
sa.ForeignKeyConstraint(['tag_id'], ['tag.id'], )
)
op.drop_constraint(u'part_part_category_id_fkey', 'part', type_='foreignkey')
op.drop_table('part_category')
op.drop_column(u'part', 'part_category_id')
### end Alembic commands ###


def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column(u'part', sa.Column('part_category_id', sa.INTEGER(), autoincrement=False, nullable=False))
op.create_foreign_key(u'part_part_category_id_fkey', 'part', 'part_category', ['part_category_id'], ['id'])
op.create_table('part_category',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('name', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
sa.Column('description', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
sa.Column('parent', sa.INTEGER(), autoincrement=False, nullable=True),
sa.Column('level', sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column('lft', sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column('parent_id', sa.INTEGER(), autoincrement=False, nullable=True),
sa.Column('rgt', sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column('tree_id', sa.INTEGER(), autoincrement=False, nullable=True),
sa.ForeignKeyConstraint(['parent_id'], [u'part_category.id'], name=u'part_category_parent_id_fkey', ondelete=u'CASCADE'),
sa.PrimaryKeyConstraint('id', name=u'part_category_pkey')
)
op.drop_table('tags')
op.drop_table('tag')
### end Alembic commands ###

+ 26
- 0
migrations/versions/55103a380b6c_.py View File

@@ -0,0 +1,26 @@
"""Add tag_slug which will contain searchable tags content

Revision ID: 55103a380b6c
Revises: 2396a54ec576
Create Date: 2016-02-03 21:01:27.255957

"""

# revision identifiers, used by Alembic.
revision = '55103a380b6c'
down_revision = '2396a54ec576'

from alembic import op
import sqlalchemy as sa


def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column('part', sa.Column('tags_slug', sa.Text(), nullable=True))
### end Alembic commands ###


def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_column('part', 'tags_slug')
### end Alembic commands ###

+ 10
- 37
models.py View File

@@ -20,6 +20,11 @@ roles_users = db.Table('roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

tags = db.Table('tags',
db.Column('tag_id', db.Integer(), db.ForeignKey('tag.id')),
db.Column('part_id', db.Integer(), db.ForeignKey('part.id'))
)


class Role(db.Model, RoleMixin):
id = db.Column(db.Integer(), primary_key=True)
@@ -56,36 +61,9 @@ class Apitoken(db.Model):
user_datastore = SQLAlchemyUserDatastore(db, User, Role)


class PartCategory(db.Model, BaseNestedSets):
__tablename__ = "part_category"
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), unique=False, nullable=True)
description = db.Column(db.String(255), unique=False, nullable=True)
parent = db.Column(db.Integer, nullable=True, default=None)
parts = db.relationship('Part', backref='part_category', lazy='dynamic')

__mapper_args__ = {"order_by": name}

def __repr__(self):
# return u"<Node (%s)>" % self.id
return u"{0} - {1}".format(self.parent.name, self.name) if self.parent else self.name

def categories_path(self, include_self=False):
_p = []
if include_self:
_p.append(self.name)

def pid(parent_id):
p = PartCategory.query.get_or_404(parent_id)
if p:
_p.append(p.name)
if p.parent_id:
pid(p.parent_id)

pid(self.parent_id)

_p.reverse()
return _p
name = db.Column(db.String(100), unique=True)


class Unit(db.Model):
@@ -382,11 +360,13 @@ class Part(db.Model):
can_be_sold = db.Column(db.Boolean(), default=False, info={'label': 'Can be sold'})
private = db.Column(db.Boolean(), default=False, info={'label': 'Private part'})

part_category_id = db.Column(db.Integer(), db.ForeignKey('part_category.id'), nullable=False)
tags_slug = db.Column(db.Text(), default="untagged")

footprint_id = db.Column(db.Integer(), db.ForeignKey('footprint.id'), nullable=True)
part_measurement_unit_id = db.Column(db.Integer(), db.ForeignKey('part_measurement_unit.id'), nullable=False)
storage_id = db.Column(db.Integer(), db.ForeignKey('storage.id'), nullable=True)

tags = db.relationship('Tag', secondary=tags, backref=db.backref('parts', lazy='dynamic'))
manufacturers = db.relationship('PartManufacturer', backref='part', cascade="all, delete-orphan")
distributors = db.relationship('PartDistributor', backref='part', cascade="all, delete-orphan")
projects = db.relationship('PartProject', backref='part', cascade="all, delete-orphan")
@@ -527,10 +507,3 @@ def del_part_attachment_files(mapper, connection, target):
safe_delete(target.get_thumbs_url('preview', fs=True))
safe_delete(target.get_uploads_url(fs=True))


@event.listens_for(PartCategory, 'before_delete')
def move_part_category(mapper, connection, target):
root = PartCategory.query.find(PartCategory.id == 2, PartCategory.name == "# Uncategorized").first()
for i in target.parts:
i.part_category_id = root.id
db.session.commit()