jamesturk/django-markupfield

AttributeError: 'NoneType' object has no attribute 'markup_type'

bbengfort opened this issue · 5 comments

Attempting to create a nullable MarkupField whose default is None:

class Person(models.Model):

    name = models.CharField(max_length=50)
    biography  = MarkupField( markup_type='markdown', blank=True, null=True, default=None)
    ...

However, when attempting to create a person object:

>>> p = Person.objects.create(**{"name": "John Doe"})
File "/lib/python2.7/site-packages/markupfield/fields.py", line 146, in pre_save
    if value.markup_type not in self.markup_choices_list:
AttributeError: 'NoneType' object has no attribute 'markup_type'

An alternate definition works:

class Person(models.Model):

    name = models.CharField(max_length=50)
    biography  = MarkupField( markup_type='markdown', blank=True, null=True, default="")
    ...

But I'd prefer not to populate my database with empty strings when they could just be NULLs.

thanks for this, I'll look into it

worth noting however that this is generally not best practice, Django docs recommend avoiding NULL on strings (see https://docs.djangoproject.com/en/1.8/ref/models/fields/)

of course, this shouldn't be an unhelpful error, I'll look into either explicitly disallowing it or making it possible

Great - thanks for looking into it! If I get a chance to dive into the code, I will.

Your advice from the Django docs is good advice - and certainly for most web applications where text is being rendered to HTML - I would 100% agree with it. I was a bit flip with my requirements (possibly due to fatigue) - I do have a semantic difference between NULL and empty string because the web application is not the only thing working with data in the database.

You may be interested in what I use your project for - I'm a researcher at the University of Maryland currently studying natural language question and answer systems. For some fields we do use standard markup, but the interesting thing we use the MarkupField for is to store automatically parsed text, like a question. The markupfield is perfect because we have raw text to store, the question:

Who is faster, a T-Rex or a Velociraptor?

But also the semantic parse, which we use to do machine learning upon:

(ROOT
  (SBARQ
    (WHNP (WP Who))
    (SQ
      (VP
        (VBZ is)
        (NP
          (NP (JJR faster))
          (, ,)
          (NP (DT a) (NN T-Rex))
          (CC or)
          (NP (DT a) (NN Velociraptor)))))
    (. ?)))

We simply view the parse as "rendered" and include in the MARKUP_FIELD_TYPES a function that performs the parsing on demand.

Back to the semantic difference between NULL and "" - we have a scheduled process that looks for all entries in the database whose parse is NULL; this indicates that we have a code-entered entry and work has to be done on it to store the "raw" and then the parse. A value of "" means that the string wasn't able to be parsed, so the scheduled process ignores it.

Anyway - we do appreciate this project, and if there is any way I can contribute more, just let me know.

OK I think I have a fix, is it possible for you to check this out

https://github.com/jamesturk/django-markupfield/compare/fix-33-null

oh and that's a really interesting use case, thanks for sharing!

Yeh - that looks like it's working; thanks a lot for the quick turn around! Cheers!

great, fixed in source, will release as 1.3.5 soon!