Skip to content

Commit

Permalink
Merge pull request #6 from paconius/master
Browse files Browse the repository at this point in the history
Extend the range of input text formats supported by the MolField Class & associated operators
  • Loading branch information
rvianello committed Oct 31, 2018
2 parents d687dfb + 9af9545 commit d0baf87
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 84 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## [Unreleased]
### Added
- README and CHANGELOG files
### Changed
- MolField values are always passed to the database as pickled Mol instances
- MolField supports parsing mol blocks and InChI input in addition to SMILES
- MolField specifies an appropriate default form field input

## [0.1.0] - 2018-08-16
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# django-rdkit
To install django-rdkit: pip install git+https://github.com/rdkit/django-rdkit.git
33 changes: 24 additions & 9 deletions django_rdkit/models/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django import VERSION as DJANGO_VERSION
from django.utils import six
from django.utils.translation import ugettext_lazy as _
from django.db.models import Lookup, Transform
from django.db.models import Lookup, Transform, Func
from django.db.models.fields import *

from rdkit.Chem import AllChem as Chem
Expand Down Expand Up @@ -47,8 +47,7 @@ def to_python(self, value):
if value is None or isinstance(value, Chem.Mol):
return value
elif isinstance(value, six.string_types):
# The string case. Assume a SMILES is passed.
return Chem.MolFromSmiles(str(value))
return self.text_to_mol(value)
elif isinstance(value, six.buffer_types):
return Chem.Mol(bytes(value))
else:
Expand All @@ -58,11 +57,22 @@ def get_prep_value(self, value):
# convert the Molecule instance to the value used by the
# db driver
if isinstance(value, six.string_types):
# The string case. A SMILES is assumed.
value = Chem.MolFromSmiles(str(value))
value = self.text_to_mol(value)
if isinstance(value, Chem.Mol):
value = six.memoryview(value.ToBinary())
return value
if value is None:
return None
return Func(value, function='mol_from_pkl')

@staticmethod
def text_to_mol(value):
value = str(value)
mol = (Chem.MolFromSmiles(value)
or Chem.MolFromMolBlock(value)
or Chem.inchi.MolFromInchi(value))
if mol is None:
raise ValidationError("Invalid input for a Mol instance")
return mol

def get_prep_lookup(self, lookup_type, value):
"Perform preliminary non-db specific lookup checks and conversions"
Expand All @@ -74,6 +84,11 @@ def get_prep_lookup(self, lookup_type, value):
return value
raise TypeError("Field has invalid lookup: %s" % lookup_type)

def formfield(self, **kwargs):
# Use TextField as default input form to accommodate line breaks needed for molBlocks
defaults = {'form_class': forms.CharField, 'strip': False, 'widget':forms.Textarea}
defaults.update(kwargs)
return super().formfield(**defaults)

##########################################
# Reaction Field
Expand Down Expand Up @@ -192,7 +207,7 @@ def get_prep_lookup(self, lookup_type, value):
class HasSubstruct(Lookup):

lookup_name = 'hassubstruct'
prepare_rhs = False
prepare_rhs = True

def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
Expand Down Expand Up @@ -222,7 +237,7 @@ def as_sql(self, qn, connection):
class IsSubstruct(Lookup):

lookup_name = 'issubstruct'
prepare_rhs = False
prepare_rhs = True

def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
Expand Down Expand Up @@ -250,7 +265,7 @@ def as_sql(self, qn, connection):
class SameStructure(Lookup):

lookup_name = 'exact'
prepare_rhs = False
prepare_rhs = True

def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
Expand Down
2 changes: 1 addition & 1 deletion tests/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Migration(migrations.Migration):
name='MoleculeModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('molecule', django_rdkit.models.fields.MolField()),
('molecule', django_rdkit.models.fields.MolField(null=True)),
],
),
migrations.CreateModel(
Expand Down
4 changes: 1 addition & 3 deletions tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class MoleculeModel(models.Model):

molecule = models.MolField()
molecule = models.MolField(null=True)


class ReactionModel(models.Model):
Expand Down Expand Up @@ -43,5 +43,3 @@ class CtabModel(models.Model):
# molecule = models.MolField()
# sfp = models.SfpField()
# bfb = models.BfpField()


0 comments on commit d0baf87

Please sign in to comment.