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
- form.instance.user= request.user in to my form_completion function.
- 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})