Frank
Frank

Reputation: 671

Django - forms.Form can't save current user and form is valid but not saved

I modified my code to use forms.ModelForm so that I can modify the width of the forms for the webpage. The problem I have now is that ForeignKeys is not available for forms.Form and I need to save the active user in the form, as well as the current time when the request is submitted.

Below are my files (I excluded all necessary imports) with the current workaround, and it gives me the following error: table chemrun_chemrun has no column named owner_id. I am happy for any help to solve this :)

from models.py

class ChemRun(models.Model):
    owner           =       models.ForeignKey('auth.User')

from forms.py

class ChemRunForm(forms.ModelForm):
    title           =       forms.CharField(max_length=50)
    status          =       forms.CharField(max_length=20, initial="In queue")
    created_date    =       forms.DateTimeField(initial=timezone.now, required=False)

    def __unicode__(self):
            return self.title

    class Meta:
            model   =       ChemRun
            exclude =       {'created_date', 'status', 'owner'}

from views.py

@verified_email_required
def create(request):
    if request.POST:
            form = ChemRunForm(request.POST)
            if form.is_valid():
                    m = form.save(commit=False)
                    m.created_date  =       timezone.now
                    m.owner         =       request.user
                    m.save()
                    return HttpResponseRedirect('/accounts/profile')
    else:
            form = ChemRunForm()

    args = {}
    args.update(csrf(request))
    args['form'] = form

    return render_to_response('interface/newrun.html', args, context_instance=RequestContext(request))

from urls.py

urlpatterns = [
    url(r'^create/$', 'chemrun.views.create', name='create'),
]

Upvotes: 0

Views: 1311

Answers (2)

Frank
Frank

Reputation: 671

After some more reading and experimenting I found some additional points to add for future readers of the question.

The first part of the error was caused by not being able to run successfully the commands makemigrations and subsequently migrate. By error I had removed __init__.py from the migrations directory. After restoring the file and rerun the commands, that part was corrected. For the future, I can recommend the following script to clean/reset migrations (taken from one of the answers to this question).

#!/bin/sh
echo "Starting ..."

echo ">> Deleting old migrations"
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete

# Optional
echo ">> Deleting database"
find . -name "db.sqlite3" -delete

echo ">> Running manage.py makemigrations"
python manage.py makemigrations

echo ">> Running manage.py migrate"
python manage.py migrate

echo ">> Done"

The second part was to be able to adjust width of the fields. I have my fields defined in models.py, but by adding a widget call to the Meta class of the equivalent form class in forms.py I had power to adjust this, and more. Here is my forms.py:

class ChemRunForm(forms.ModelForm):
    class Meta:
        model = ChemRun
        widgets =       {'title': forms.TextInput(attrs={'style':'width: 500px;'})}
        exclude = ('owner')

NB: ChemRun is the models class, ChemRunForm is the forms class. title and owner are two of the fields for my model.

Hope this will help people in the future

Upvotes: 0

diegueus9
diegueus9

Reputation: 31522

I see two practical solutions to your problem:

  1. Since the field 'owner' is new to the model, you will have to add a default id in the migration to put that in the column to the already existent data.
  2. You could set 'blank=null' in the 'owner' field, in that way django it will not force the data in that column.

You said in the comments that before the command 'makemigrations' didn't ask you for anything and now it does, this is because now you have records in that table and if you add a new column, neither django or postgres know what to put in that column in the old records, perhaps you could 'flush' your database? Of course, only if it is a dev database.

Upvotes: 1

Related Questions