Code

Opened 5 years ago

Last modified 6 months ago

#10244 new Bug

FileFields can't be set to NULL in the db

Reported by: oyvind Owned by: nobody
Component: Database layer (models, ORM) Version: 1.0
Severity: Normal Keywords: filefield NULL empty
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: yes
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Saving FileFields with a none value sets the field to a empty string in the db and not NULL as it should.

Attachments (4)

filefield_null.diff (793 bytes) - added by oyvind 5 years ago.
Patch that solves this issue, FieldFile's name can now be None also "is" and "==" is not the same
null-filefield.diff (2.0 KB) - added by Alex 5 years ago.
null-filefield-2.diff (2.4 KB) - added by oyvind 5 years ago.
Meade FieldFile set name to u on delete, made test show filefields and charfields act the same
filefield_null.patch (1.4 KB) - added by siroky@… 6 months ago.
None/NULL for FileField (v1.5.1)

Download all attachments as: .zip

Change History (19)

comment:1 Changed 5 years ago by oyvind

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Patch does not seem to work quite like I expected. So the problem persists.

comment:2 Changed 5 years ago by oyvind

Example to test this issue:

                
class File(models.Model):

    file = models.FileField(null=True, upload_to='files') 
from models import File

f = File()
f.file = None
f.save()

from django.db import connection
print connection.queries

Changed 5 years ago by oyvind

Patch that solves this issue, FieldFile's name can now be None also "is" and "==" is not the same

Changed 5 years ago by Alex

comment:3 Changed 5 years ago by Alex

  • Triage Stage changed from Unreviewed to Design decision needed

needs to be decided whether the CharField behavior should be used throughout, or NULL where explicitly requested

Changed 5 years ago by oyvind

Meade FieldFile set name to u on delete, made test show filefields and charfields act the same

comment:4 Changed 5 years ago by kmtracey

Dev list discussion: http://groups.google.com/group/django-developers/browse_thread/thread/cf37abc95e49f0e/

Also, #10749 reported surprise at searching for None not working when looking for empty ImageFields. I still think changing this now breaks backwards-compatibility, though.

comment:5 Changed 5 years ago by thejaswi_puthraya

  • Component changed from Uncategorized to Database layer (models, ORM)

comment:6 Changed 3 years ago by SmileyChris

  • Severity set to Normal
  • Type set to Bug

comment:7 Changed 2 years ago by aaugustin

  • Easy pickings unset
  • Triage Stage changed from Design decision needed to Accepted
  • UI/UX unset

I see two possible solutions:

  • 1. document that FileField ignores the null keyword argument; this is the most backwards compatible solution;
  • 2. make FileField behave exactly like CharField wrt. null; this is the most consistent solution.

Option 2. will be backwards incompatible only for people who set null=True on a FileField. The docs discourage that heavily, and it doesn't behave as expected, actually it doesn't even do anything, so there isn't much reason to have such code. That's why I think the change would be acceptable.

I have a slight preference for option 2, which is better in the long term.

comment:8 Changed 6 months ago by siroky@…

Hi! What is the status of this ticket? I see it is 5 years old ticket and the problem is still present at least in 1.5.1.

comment:9 Changed 6 months ago by aaugustin

It's waiting for someone to write a patch.

Changed 6 months ago by siroky@…

None/NULL for FileField (v1.5.1)

comment:10 Changed 6 months ago by siroky@…

How about the filefield_null.patch? It follows solution 2.

comment:11 Changed 6 months ago by claudep

  • Has patch set
  • Needs documentation set
  • Needs tests set

Thanks, it's a first step :-) However, tests are crucial with such a change. That will be the next step. See FileFieldTestsin tests/model_fields/tests.py.

comment:12 Changed 6 months ago by anonymous

How can I run the FileFieldTests without the whole suite?

comment:14 Changed 6 months ago by siroky@…

I bumped into a problem. If instance.null_file_field is None then methods like save() will not work (AttributeError: 'NoneType' object has no attribute 'save'). I'm thinking about 2 solutions:
1) Make the descriptor return value comparable to None (via __eq__). This is not very clean because the best practise is to use operator is (is_none = x is None).
2) Keep the empty string ("") on the Python side as a representation of file's database NULL. Not very consistent but it has better backward compatibility if someone already uses the string comparison (has_no_file = filefield.name == "").

Any suggestions?

comment:15 Changed 6 months ago by anonymous

So? :-)

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.