Repository: TOMToolkit/tom_base

Issue:
Target/Extra in admin does not allow for empty values
**Describe the bug**
When editing my db in /admin/ zone for Target-Extra fields, I am not allowed to SAVE without setting any value to all fields, even if they were empty before. This works in TOM in Create or Update, where I can leave those fields with empty value, but in admin. 
This could be django thing actually.

**To Reproduce**
Go to /admin/
Targets
select any target and scroll down to the extra fields.
You need a new field which has no value defined. 
If you click SAVE, django gives and error as shown in the screenshot.

**Expected behavior**
If the field value was not previously defined, leave it undefined at Save.

**Desktop (please complete the following information):**
 - Mac OS
 - Chrome
 - TOM 1.2.3
 - Python Version 3.7.1


![image](https://user-images.githubusercontent.com/26644157/70483083-4d296400-1a9c-11ea-9114-749fe6af54e7.png)



Discussion:
@wyrzykow I'm not sure this is a bug--to be clear, there are two types of extras.

1. Extras as defined in `EXTRA_FIELDS` in `settings.py`. A defined `EXTRA_FIELD` creates a field in the Target create and update forms, that can be left blank.
2. Extras NOT defined in `EXTRA_FIELDS`, also known as "tags", _must_ have a value, or be deleted. Otherwise it doesn't really make sense if they exist at all.

I can't see your db, but I'm assuming that `ztf_alert_name` is **not** defined in `settings.py` as an `EXTRA_FIELD`, would that be correct? Or is it defined as such?
Hi David,

I realised there are two sets of extras, but I am only using those set in settings. ztfname is set in settings. 

cheers,

Łukasz from the phone

> On 10 Dec 2019, at 10:43, David Collom <notifications@github.com> wrote:
> 
> @wyrzykow I'm not sure this is a bug--to be clear, there are two types of extras.
> 
> Extras as defined in EXTRA_FIELDS in settings.py. A defined EXTRA_FIELD creates a field in the Target create and update forms, that can be left blank.
> Extras NOT defined in EXTRA_FIELDS, also known as "tags", must have a value, or be deleted. Otherwise it doesn't really make sense if they exist at all.
> I can't see your db, but I'm assuming that ztf_alert_name is not defined in settings.py as an EXTRA_FIELD, would that be correct? Or is it defined as such?
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub, or unsubscribe.

So I suspect that it doesn't save the "no value" in either case, it just happens to pass validation in the non-admin view. This is a result of the implementation--we _might_ be able to work a fix in, but I don't want to promise anything. Is it something you feel is essential?
Having discussed this with Lukasz, I think it's safe to say that a field should be able to be cleared without resorting to the admin interface.

Resolving patch:
diff --git a/tom_targets/migrations/0016_auto_20191211_1707.py b/tom_targets/migrations/0016_auto_20191211_1707.py
new file mode 100644
--- /dev/null
+++ b/tom_targets/migrations/0016_auto_20191211_1707.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.8 on 2019-12-11 17:07
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tom_targets', '0015_auto_20190923_2233'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='targetextra',
+            name='value',
+            field=models.TextField(blank=True, default=''),
+        ),
+    ]
diff --git a/tom_targets/models.py b/tom_targets/models.py
--- a/tom_targets/models.py
+++ b/tom_targets/models.py
@@ -411,7 +411,7 @@ class TargetExtra(models.Model):
     """
     target = models.ForeignKey(Target, on_delete=models.CASCADE)
     key = models.CharField(max_length=200)
-    value = models.TextField()
+    value = models.TextField(blank=True, default='')
     float_value = models.FloatField(null=True, blank=True)
     bool_value = models.BooleanField(null=True, blank=True)
     time_value = models.DateTimeField(null=True, blank=True)


Test patch: