Home > Software engineering >  With Django, connecting a User to a completed Form?
With Django, connecting a User to a completed Form?

Time:08-11

Right now, users can view all forms that are completed by any user, even when they are logged in and all forms get posted onto the same html page. I want users to only be able to view their own forms they completed when logged into their account. Any directions would be helpful. I understand functions more than classes in views, an ideal solution would use functions. Thank you so much for any advice as this is my first Django I am trying on my own without strictly following a video or class.

models.py

from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
from django import forms

class Step1_Model(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
    title = "STEP 1: Safety during a violent incident"
    box1 = models.CharField(max_length=100, null=True)
    box2 = models.CharField(max_length=100, null=True)
    box3 = models.CharField(max_length=100, null=True)
    box4 = models.CharField(max_length=100, null=True)
    box5 = models.CharField(max_length=100, null=True)
    box6 = models.CharField(max_length=100, null=True)
    
    def __str__(self):
        return self.title
forms.py

from django import forms
from .models import Step1_Model

class Step1_Form(forms.ModelForm):
    box1 = forms.CharField()

    class Meta: 
        model = Step1_Model  #which model we want to use as a model for our model form
        fields= ("box1","box2","box3", "box4", "box5", "box6")
views.py

from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import Step1_Form
from .models import Step1_Model
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required

def loginPage(request):

    if request.method == "POST": #The user entered the info and logged in.
        username = request.POST.get('username') #this is sent from the front end through the login.html.
        password = request.POST.get('password')
        try:
            user= User.objects.get(username=username)
        except:
            messages.error(request, "User does not exist.")
        user = authenticate(request, username=username, password=password) #if get was successful authenticate user.
        if user is not None: #if we got a user
            login(request, user) #will add the session in the database and browser.
            return redirect('home')
        else:
            messages.error(request, "Username or password does not exist.")
    context = {}
    return render(request, 'registration/login_registration.html', context)

def logoutUser(request):
    logout(request) # deletes the token/user session
    return redirect('home')

@login_required(login_url='login_user') 
def Step1_Form_Completion(request):
    """Generates link for user to fill out form"""
    form = Step1_Form                #Assign the form to the variable in the function.
    if request.method == 'POST':     # if method or form is requested then POST or send data to this function. If someone is loggded in . . 
        form = Step1_Form(request.POST) #the method is form and it is to be posted.
        if form.is_valid():             #if the form is django's definiton for 'valid' then save it and redirect the user home.
            form.save()
            return redirect('/')
    return render(request, 'form.html', {'form':form} ) # return  this function to the form.html page and let it use form as s variable and call it's attributes (form.box1)

@login_required(login_url='login_user')  #sends user back to login page if they try to go to a view form.
def Step1_Form_View(request):
    """View for user to see completed form"""
    step1 = Step1_Model.objects.all()   
    return render(request,'form_view.html',{'step1': step1})


def index(request):
    return render(request, 'index.html')

def register_user(request):
    form = UserCreationForm()
    if request.method == 'POST': #if someone has filled out a form do something.
        form = UserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data['username']
            password = form.cleaned_data['password1']
            user = authenticate(username=username, password=password) #authenticate user
            login(request, user)  #log user in
            messages.success(request, 'Registration Successful')
            return redirect('home')
        else:
            form = UserCreationForm()
    return render(request, 'registration/register_user.html', {'form': form} )
urls.py

from django.urls import path
from . import views 

urlpatterns = [

    path('login', views.loginPage, name='login_user'),
    path('logout', views.logoutUser, name='logout'),
    path('register_user', views.register_user, name='register_user'),


    path('', views.index, name='home'),

    path('step1', views.Step1_Form_Completion, name='step1'),
    path('form_view', views.Step1_Form_View, name='form_view'),

]
form.html

{% block content %}


</head>
<body>
        <form method='post'>
            {% csrf_token %}
        
        STEP 1: Safety during a violent incident. I will not always be able to avoid violent incidents. In order to increase safety I may use a variety of strategies.
        I can use some of the following strategies:
        <p>
        A. When I need to leave the house because of an emergency I will keep my keys in: {{ form.box1 }}. 
        <p>
        B. When I need to put out a fire I will:{{ form.box2 }}.
        </p>
        </p>
        <button type="submit">Submit</button>
        </form>
</body>
</html>

{% endblock content %}


form_view.html
<body>
<!-- user_input shows up here but way too much. not only the logged in users form.-->

{% if step1 %}
 <h1>Your Step 1 Plan</h1>

 <tr>
     {% for st in step1 %}
    <p>
    A.  I will <b>{{ st.box1 }}</b>. 
    <p>
    B. I will put the fire out by <b>{{ st.box2 }}</b> in order to leave quickly.
    </p>
index.html 
<!-- my homepage and how users get to view wand submit forms-->
{% extends 'base.html' %}

{% block content %}

<!--Row 1-->
  <div >
    <div >
      <p>{{request.user}}</p>
    </div>


<!--Row 2-->
  <div >

    <div >
      Step 1: A Violent Incident
    </div>

    <div >
        <a href="{%  url 'step1'  %}">Form</a>
    </div>

    <div >
        <a href="{% url 'form_view'  %}">View</a>
    </div>

  </div>
{% endblock %}

CodePudding user response:

Instead of passing all Step1_Model in view just pass that one asign to request.user

@login_required(login_url='login_user')  #sends user back to login page if they try to go to a view form.
def Step1_Form_View(request):
    """View for user to see completed form"""
    step1 = request.user.step1_model 
    return render(request,'form_view.html',{'step1': step1})

now you don't need {% for st in step1 %} in form_view.html template.

And for future readability use PascalCase in class names(models, forms, etc), you don't need to add 'model' to class name, and snake_case for function names.

CodePudding user response:

Found the answer for this if anyone wants to know, I haven't seen this answer online anywhere. I had to watch more videos about how accessing the database works. I needed to add two lines of code: In views.py

  1. form.instance.user= request.user in to my form_completion function.
  2. step1 = StepOne.objects.filter(user=request.user) into my form_view function.

See below for an example:

@login_required(login_url='login_user') 
def Step1_Form_Completion(request):
    """Generates link for user to fill out form"""
    form = StepOneForm                #Assign the form to the variable in the function.
    if request.method == 'POST':     # if method or form is requested then POST or send data to this function. If someone is loggded in . . 
        form = StepOneForm(request.POST) #the method is form and it is to be posted.
        if form.is_valid():             #if the form is django's definiton for 'valid' then save it and redirect the user home.
            form.instance.user= request.user
            form.save()
            return redirect('/')
    return render(request, 'form.html', {'form':form} ) # return  this function to the form.html page and let it use form as s variable and call it's attributes (form.box1)
@login_required(login_url='login_user')  #sends user back to login page if they try to go to a view form.
def Step1_Form_View(request):
    """View for user to see completed form"""
    step1 = StepOne.objects.filter(user=request.user)
    return render(request,'form_view.html',{'step1': step1})
  • Related