0

Python noob here trying to learn something very simple.

I'm trying to create a basic form that takes some personal information from a user and saves it into a sqlite3 table with the username of the user as the primary key.

My models.py looks like this:

class userinfo(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key= True, 
on_delete=models.CASCADE)
    name = models.CharField(max_length = 200, blank = True)
    email = models.EmailField(max_length= 300, default = 'Null')
    phone = models.CharField(max_length= 10, default = 'Null')

def __unicode__(self):
    return self.user

forms.py:

class NewList(forms.ModelForm):

    class Meta:
        model = userinfo
        exclude = {'user'}

views.py

def newlist(request):
    if request.method == 'POST':
        form = NewList(request.POST)
        if form.is_valid():
            Event = form.save(commit = False)
            Event.save()
            return redirect('/home')

    else:
        form = NewList()

    return render(request, 'home/newlist.html', {'form': form})

html:

{% load static %}

<form action="/home/" method="post">

{% csrf_token %}
{{ form.as_p }}

<input type="submit">

</form>

urls.py too, but I don't know how that would help:

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

So when I go to the url, I see the form. I can then fill the form, but when I submit the form, the data doesn't go into the database.

What am I doing wrong here?

Thanks in advance!

2
  • 1
    Not the problem, but you really should give things consistent names. Your model is called userinfo, but the form is called NewList and the result of saving is called Event. Commented Dec 2, 2017 at 19:40
  • What do you see then, any error etc. Is your action path working? Commented Dec 3, 2017 at 0:04

1 Answer 1

2

I think all you need to do is just save the form if it's valid, probably also add the userinfo as an instance of the form. You are also exluding the user from the form and need to assign it manually.

def newlist(request):
    if request.user.is_authenticated():
        user = request.user

        if request.method == 'POST':
            form = NewList(request.POST, instance=user.userinfo)
            if form.is_valid():
                form.save(commit=false)  
                form.user = user          
                form.save()
                return redirect('/home')
        else:
            form = NewList(instance=user.userinfo) # add this if you want it to automatically fill the form with the old data if there is any.

    return render(request, 'home/newlist.html', {'form': form})

The rest look like it should work.Except you need to send the post URL back to newlist:

{% load static %}
<form action="/newlist/" method="POST">

{% csrf_token %}
{{ form.as_p }}
</form>

If users are assigned at the creation of the model the first time, you don't need the user save, but since this is saving a users data you want to make sure they are logged in anyway:

def newlist(request): 
    if request.user.is_authenticated(): 
        user = request.user 
        if request.method == 'POST':
            form = NewList(request.POST, instance=user.userinfo)
            if form.is_valid():          
                form.save()
                return redirect('/home')
        else:
            form = NewList(instance=user.userinfo) # add this if you want it to automatically fill the form with the old data if there is any.

    return render(request, 'home/newlist.html', {'form': form})

The instance is the model it is either going to save to, or copying data from. In the: form = NewList(request.POST, instance=user.userinfo) part, it is taking the POST data from the form, and linking that to the specific model entry of user.userinfo, however, it will only save to the database when you call form.save().

The user.userinfo is just so you can get the correct form to save to, as userinfo is a onetoone model to user. Thus making it possible to get it with user.userinfo.

The form = NewList(instance=user.userinfo) part is where it takes the currently logged in user's userinfo and copies into the form before it is rendered, so the old userinfo data will be prefilled into the form in the html. That being if it got the correct userinfo model.

Sign up to request clarification or add additional context in comments.

8 Comments

maybe the action part is the main problem here :) p.s but let see what the op has to say about it
yeah, I noticed that after the fact, the function wasen't even being called with post data.
Hi, I tried this. I get this error: NameError at /home/newlist/ global name 'user' is not defined
@user241691 the main issue was that in the form action, you sen't the POST data to a url that you did not have set up to handle this data. Your logic was in the same url as the page itself. Which normally works as you want it. However you can POST to a different URL that does something, then redirect you. But always POST to a view that handle the data. I added some explanation to my answer about the instance part.
The only books that I own myself is the hellowebbooks.com which goes trough setting up and deploying a django app from scratch. A freebie(can buy a hard copy) is the obeythetestinggoat.com which explains with an example project how to do TDD. Another that I have yet to buy is twoscoopspress.com/products/two-scoops-of-django-1-8 which seem to be highly recommended. If you want a more "teacher" like experience there is teamtreehouse.com which actually have code challenges and quizzes as part of their courses. These go trough the more basic stuff.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.