2017-12-31 140 views
0

Ich versuche ein benutzerdefiniertes Feld zu erstellen. Es basiert auf postgres.JSONField.Muss get_prep_value() mit value = None umgehen?

class CardiosField(JSONField): 
    """Field representing a models.Cardios object""" 

    def from_db_value(self, value, expression, connection): 
     if value is None: 
      return value 
     return parse_cardios(value) 

    def to_python(self, value): 
     if isinstance(value, models.Cardios): 
      return value 
     if value is None: 
      return value 
     return parse_cardios(value) 

    def get_prep_value(self, value): 
     cardios_pre_json = [serie_object.pre_json() for serie_object in value.series] 
     return json.dumps(cardios_pre_json) 

Ich habe ein Modell erstellt, das dieses Feld hat:

class Workout(models.Model): 

    datetime = models.DateTimeField() 
    user = models.ForeignKey(User, on_delete=models.CASCADE) 
    lifts = fields.LiftsField(null=True) 
    cardios = fields.CardiosField(null=True) 

    def __str__(self): 
     return str(self.datetime)+" "+self.user.email 

    __repr__ = __str__ 

ich Migrationen ohne Probleme machen, aber wenn ich zu migrieren versuchen, dies geschieht:

(workout) Sahands-MBP:workout sahandzarrinkoub$ python manage.py migrate 
Operations to perform: 
    Apply all migrations: admin, auth, contenttypes, sessions, workoutcal 
Running migrations: 
    Applying workoutcal.0003_auto_20171231_2308...Traceback (most recent call last): 
    File "manage.py", line 22, in <module> 
    execute_from_command_line(sys.argv) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line 
    utility.execute() 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute 
    output = self.handle(*args, **options) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle 
    fake_initial=fake_initial, 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate 
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards 
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration 
    state = migration.apply(state, schema_editor) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/migrations/migration.py", line 129, in apply 
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 87, in database_forwards 
    field, 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 415, in add_field 
    definition, params = self.column_sql(model, field, include_default=True) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 155, in column_sql 
    default_value = self.effective_default(field) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 229, in effective_default 
    default = field.get_db_prep_save(default, self.connection) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 770, in get_db_prep_save 
    prepared=False) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 762, in get_db_prep_value 
    value = self.get_prep_value(value) 
    File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/workout/workoutcal/fields.py", line 52, in get_prep_value 
    cardios_pre_json = [serie_object.pre_json() for serie_object in value.series] 
AttributeError: 'NoneType' object has no attribute 'series' 

Does get_prep_value() haben mit None zu tun haben? Ich habe die docs gelesen und dies scheint nicht der Fall zu sein, zumindest nicht in ihrem Codebeispiel. Kann mir jemand erklären, was hier schief läuft?

+1

Ja, es hat mit 'None' beschäftigen, wenn Sie Erlaube NULL-Werte auf dem Feld (was du tust - du hast 'null = True' auf dem Feld gesetzt. – solarissmoke

+0

Und was soll es tun, wenn 'value = None'? – Sahand

+1

Es sollte einfach 'None' zurückgeben – solarissmoke

Antwort

0

Danke @solarissmoke für diese Lösung:

get_prep_value hat mit None beschäftigen, da ich null=True für das Feld festgelegt haben:

def get_prep_value(self, value): 
    if not value: 
     return value 
    cardios_pre_json = [serie_object.pre_json() for serie_object in value.series] 
    return json.dumps(cardios_pre_json) 
Verwandte Themen