Django forms are not saving any information - python

So I have been trying to build a manager of activities with django and I'm still on the scratch. I was trying to test if the code can simply show if a acitivity is done or not, but it don't change anything. Everything looks good to me and I don't know if the error is in the form, in the view that saves the form or in anything else. I already tried to change the widget and fields of form and haven't been succeed in it.
models.py:
from django.db import models
from django.contrib.auth.models import User
class Activity(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=30)
is_complete = models.BooleanField()
def __str__(self):
return self.title
forms.py:
from .models import Activity
class ActivityUpdateForm(ModelForm):
class Meta:
model = Activity
fields = ['is_complete']
views.py:
from .models import Activity
from .forms import ActivityUpdateForm
def home(request):
acts = Activity.objects.all()
if request.method == 'POST':
form = ActivityUpdateForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('home')
else:
form = ActivityUpdateForm()
context = {
'acts': acts,
'form': form,
}
return render(request, 'diary/home.html', context)
template:
{% for act in acts %}
<form method="POST">
{% csrf_token %}
<p>{{ act.title }}</p>
<p>Is complete: {{ act.is_complete }}</p>
{{ form }}
<p>{{ act.author }}</p>
<button type="submit">Submit</button>
</form>
{% endfor %}```

This is not elegant, but you just might need to do this:
data = Activity.objects.get(author=request.user)
data.is_complete = form.cleaned_data["is_complete"]
data.save()
Please delete form.save() and write the code above.
i'm not sure if this works, but please give it a try.

Related

Model form data not showing up in database. Form not saving data

The form I created is not inserting the data into my database table. As far as I can tell I've done everything correctly but it still refuses to save into the database. Instead it "post" in the console and clears the form fields without creating nothing in the database. None of the data that is being entered is being saved anywhere? This is extremely confusing considering that I've done everything correctly.
ps. I've connected my database, ran migrations and created a superuser as well but still nothing.
models.py
from django.db import models
Media_Choices = (
("TV", "TV"),
("Radio", "Radio"),
("Youtube", "Youtube"),
("Podcast", "Podcast"),
)
class Appear(models.Model):
Show = models.CharField(max_length=100)
Media = models.CharField(max_length=30, blank=True, null=True, choices=Media_Choices)
Episode = models.IntegerField()
Date = models.DateField(max_length=100)
Time = models.TimeField(auto_now=False, auto_now_add=False)
Producer = models.CharField(max_length=100)
Producer_Email = models.EmailField(max_length=254)
def __unicode__(self):
return self.Show + ' ' + self.Producer_Email
forms.py
from django import forms
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from .models import Appear
class AppsForm(ModelForm):
class Meta:
model = Appear
fields = '__all__'
views.py
from django.shortcuts import redirect, render
from django.http import HttpResponse
from .forms import AppsForm
from .models import Appear
def AppS(request):
if request == 'POST':
form = AppsForm(request.POST)
if form.is_valid():
Apps = form.save(Commit=False)
Apps.save()
else:
form = AppsForm()
return render(request, 'AppsForm.html', {'form': form})
def results(request):
return render(request, 'Results.html')
AppsForm.html
<body>
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
<form action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" value="submit">
</form>
{% endblock %}
Two Correction :
First : In AppsForm.html
<form action="" method="POST">
Provide a url to your form, where it should submit data
<form action="{% url 'url_name_for_Apps_view' %}" method="POST">
Second : In AppS view
This should be
if request == 'POST':
if request.method == 'POST':

Cannot get data into my database using django model forms

The form I created is not inserting the data into my database table. As far as I can tell I've done everything correctly but it still refuses to do so instead it "post" in the console and clears the form fields without creating nothing in the database. None of the data that entered is saved anywhere? Here are the files below hopeful someone can see something I'm missing.
ps. I've connected my database, ran migrations and created a superuser as well but still nothing.
models.py
from django.db import models
Media_Choices = (
("TV", "TV"),
("Radio", "Radio"),
("Youtube", "Youtube"),
("Podcast", "Podcast"),
)
class Appear(models.Model):
Show = models.CharField(max_length=100)
Media = models.CharField(max_length=30, blank=True, null=True, choices=Media_Choices)
Episode = models.IntegerField()
Date = models.DateField(max_length=100)
Time = models.TimeField(auto_now=False, auto_now_add=False)
Producer = models.CharField(max_length=100)
Producer_Email = models.EmailField(max_length=254)
def __unicode__(self):
return self.Show + ' ' + self.Producer_Email
forms.py
from django import forms
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from .models import Appear
class AppsForm(ModelForm):
class Meta:
model = Appear
fields = '__all__'
def clean_Producer_Email(self):
Producer_Email = self.cleaned_data.get('Producer_Email')
if (Producer_Email == ""):
raise forms.ValidationError('field cannot be left empty')
for instance in Appear.objects.all():
if instance.Producer_Email == Producer_Email:
raise forms.ValidationError('Please fill in correct email')
return Producer_Email
views.py
from django.shortcuts import redirect, render
from django.http import HttpResponse
from .forms import AppsForm
from .models import Appear
def AppS(request):
if request == 'POST':
form = AppsForm(request.POST)
if form.is_valid():
Apps = form.save(Commit=False)
Apps.save()
else:
form = AppsForm()
return render(request, 'AppsForm.html', {'form': form})
def results(request):
return render(request, 'Results.html')
AppsForm.html
<body>
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
<form action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" value="submit">
</form>
{% endblock %}
enter code here
You might be missing form errors due to which the form is not saving. Try printing if there are any form errors.
if form.is_valid():
Apps = form.save(Commit=False)
Apps.save()
else:
print(form.errors)

Why is my Django form not "valid"? Can't get the POST request to update database

I am trying to create a user profiles for users in my Django app. I have the form displaying where I want it to and when I try to submit, nothing happens.
I put a print statement after the form.is_valid in my view.py and found that it wasn't 'valid' but I have no idea why.
I have tried several different ways to 'clean' / 'validate' data but I can't get past the form being 'invalid.'
Any help would be greatly appreciated!
urls:
path('userinfo/', views.user_info, name='userinfo')
form template:
{% extends "base.html" %}
{% load bootstrap4 %}
{% block content %}
<div class="container">
<h1>Enter User Info</h1>
<form method="POST" class="form">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit" class="btn btn-primary" value="Create Profile">
</form>
</div>
{% endblock %}
view:
def user_info(request):
form = ProfileForm()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
form.save()
else:
form = ProfileForm()
return render(request, 'miraDashboard/form.html', context={'form': form})
model:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
name = models.CharField("Full Name", max_length=1024)
job_role = models.CharField("Role", max_length=254, default="Seeking Job Opportunities")
zip_code = models.CharField("Zip Code", max_length=5)
user_image = models.ImageField("Upload Profile Picture", upload_to='images/')
def __str__(self):
return f'{self.user.username} Profile'
form:
from django.forms import ModelForm
from .models import Profile
class ProfileForm(ModelForm):
class Meta:
model = Profile
fields = ['name','job_role','zip_code', 'user_image']
if you want to see errors in form change else statmant:
def user_info(request):
form = ProfileForm()
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
form.save()
else:
print(form.errors.as_data()) # here you print errors to terminal
return render(request, 'miraDashboard/form.html', context={'form': form})
after form.is_valid() you don't need to set it again (form = ProfileForm() in else statment). this way your form will get errors( you cen see them in form.errors).

I am try to get object of the logged in user in django? This list that is been created while form.save of the user that is logged in

Hello as I posted here before I new to django python need some help on how to get objects of a user that is currently logged in. I have an app named stores which contains a models named Store. I just want to gather the list of stores a user created. Do I have to add anything in setting.py ?
I am really confused about it I also tried request.user and tried to filter the object but I wasn't able to do it. I am posting my code over here kindly look into it and do let me know.
Do let me know if you need anything else to understand.
views.py of stores app
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import NewStore
from .models import Store
def store(request):
form = NewStore()
if request.method == 'POST':
form = NewStore(request.POST)
if form.is_valid():
form = form.save()
return redirect('stores_list')
else:
form = NewStore()
return render(request, "default/store.html", {'form': form})
#login_required()
def stores_list(request):
my_stores = Store.objects.all()
print(my_stores)
return render(request, "default/stores_list.html", {'my_list': my_stores})
models.py of stores app
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Store(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
lat = models.DecimalField(max_digits=50, decimal_places=20)
long = models.DecimalField(max_digits=50, decimal_places=20)
type = models.CharField(max_length=30)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.name
stores_list.html
{% extends 'default/base.html' %}
<html>
<head><title>E-Commerce App</title></head>
{% block content %}
<h1>Welcome to your profile</h1>
<h2>Stores List</h2>
<p>This is your store list</p>
<ul>
{% for s in my_list %}
<li> Store {{ s.id }}: {{ s.name }} </li>
{% endfor %}
</ul>
{% endblock %}
</html>
Change this
if request.method == 'POST':
form = NewStore(request.POST)
if form.is_valid():
form = form.save()
return redirect('stores_list')
to
if request.method == 'POST':
form = NewStore(request.POST)
if form.is_valid():
entry = form.save(commit=False)
# Attach logged-in user details with the 'store' entry
entry.user = request.user
entry.save()
return redirect('stores_list')
To get the store list, created under the logged in user, use
logged_in_user = request.user
store_list = Store.objects.filter(user=logged_in_user)
You need to filter all stores for those belonging to the current user:
#login_required()
def stores_list(request):
my_stores = Store.objects.all().filter(user=request.user)
print(my_stores)
return render(request, "default/stores_list.html", {'my_list': my_stores})

Output username from user_id field on separate model in Django Template

When a post is created, the user's User ID is saved to the post table under the user_id field. On the home page (for right now) I'm outputting all the posts in the post table. I want to get the username into the template based off of the user ID on the Post object.
models.py
class Post(models.Model):
user_id = models.IntegerField()
post_name = models.CharField(max_length=300)
total_votes = models.IntegerField(default=0)
created_date = models.DateTimeField()
views.py
#login_required
def home(request):
posts = Post.objects.raw('SELECT * FROM posts ORDER BY created_date DESC')
return render(request, 'home.html', {'posts': posts})
home.html
{% for post in posts %}
<div>
{{ post.post_name }}
<p>{{ post.created_date }}</p>
<p>{{ post.total_votes }}</p>
<p>{{ post.user_id }}</p>
</div>
{% endfor %}
Edit: Ended up changing query to:
SELECT
*, u.username
FROM posts p
LEFT JOIN auth_user u ON (p.user_id = u.id)
I didn't think you could add to the Post object and even call it as post.username. Regardless, if there's a better way to do it, let me know. Thanks!
Your whole logic is wrong :(
The user should be stored as a ForeignKey into the Post model. That is, a user may have multiple Posts but one Post may belong to one user. Something like that:
class Post(models.Model):
user = models.ForeignKey(User, related_name='posts')
post_name = models.CharField(max_length=300)
total_votes = models.IntegerField(default=0)
created_date = models.DateTimeField()
Note that the User model may be the built-in Django User model (from django.contrib.auth.models import User) or you own if you have customized it.
Database queries in Django, are not made with raw SQL. That's why the ORM exists. So, the view could be changed to:
#login_required
def home(request):
posts = Post.objects.order_by('-created_date')
return render(request, 'home.html', {'posts': posts})
Now you have a very verbose and pythonic access to the User model instance (and to the Post one) from your template.
{% for post in posts %}
<div>
{{ post.post_name }}
<p>{{ post.created_date }}</p>
<p>{{ post.total_votes }}</p>
<p>{{ post.user.username }}</p>
</div>
{% endfor %}
EXTRA TIP: Instead of href="posts/{{post.id}}", try to use the {% url %} template tag in order not to hardcode url paths like that.
It would be better to use ForeignKey for such purpose. For example:
class Post(models.Model):
user = models.ForeignKey(User)
post_name = models.CharField(max_length=300)
total_votes = models.IntegerField(default=0)
created_date = models.DateTimeField()
Make sure to import User in models.py.
Create a Form for creating Post:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('post_name',)
Now, in views:
def create_post(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
return # Write return here
else:
form = PostForm()
context = {
'form': form
}
return render(request, 'template_name', context)
Create a template for this and use it to create posts.
In your view home:
#login_required
def home(request):
posts = Post.objects.order_by('-created_date')
return render(request, 'home.html', {'posts': posts})
In your template:
{% for post in posts %}
<div>
{{ post.post_name }}
<p>{{ post.created_date }}</p>
<p>{{ post.total_votes }}</p>
<p>{{ post.user.username }}</p>
</div>
{% endfor %}
It will work.

Categories

Resources