correct using get_or_create? - python

To my code, which records a contact from the form and adds it to the db, need to add get_or_create, or write another condition (if there is a contact with such a phone — update, no - add), but i'm do it for the first time, please, I'll be glad to read solution to my problem and a brief explanation ♡
views.py
from django.http import HttpResponse
from django.shortcuts import render,redirect
from django.contrib import messages
from .forms import Forms
def main(request):
form = Forms
if request.method == "POST":
form = Forms(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Form has been submitted')
return redirect('/')
return render(request, 'app/main.html', { 'form':form } )
forms.py
from django.forms import ModelForm
from .models import Form
class Forms(ModelForm):
class Meta:
model = Form
fields = '__all__'
urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls'))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
models.py
from django.db import models
class Form(models.Model):
name = models.CharField(max_length=30)
phone = models.CharField(max_length=30)
admin.py
from django.contrib import admin
from .models import Form
'''from django.contrib.admin.models import LogEntry
LogEntry.objects.all().delete()'''
'''for delete actions in admin_panel'''
admin.site.register(Form)
apps.py
from django.apps import AppConfig
class AppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app'
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTE-8">
<meta name="viewport" content="width, initial-scale=1.0">
<title>CHECK DATA</title>
</head>
<body>
{% for message in messages %}
<p>{{message}}</p>
{% endfor %}
<form action="" method="post">
{% csrf_token %}
<table>
{{form.as_table}}
<tr>
<td colspan="2">
<input type="submit"/>
</td>
</tr>
</table>
</form>
</body>
</html>

You can implement this with:
def main(request):
if request.method == "POST":
form = Forms(request.POST)
if form.is_valid():
Form.objects.get_or_create(
phone=form.cleaned_data['phone'],
defaults={'name': form.cleaned_data['name']}
)
messages.success(request, 'Form has been submitted')
return redirect('/')
else:
form = Forms()
return render(request, 'app/main.html', { 'form': form })
You must be careful however since this means that a user might edit data of another user. Perhaps it is thus worth to check if the (logged in) user has rights to update that item.

Related

How to return form values and upload file at the same time in Django?

I am a beginner at Django. I want to let users fill in Form and upload a file to the specific folder at the same time, and get the form value they filled in.
Here is my forms.py
from django import forms
class UserForm(forms.Form):
first_name= forms.CharField(max_length=100)
last_name= forms.CharField(max_length=100)
email= forms.EmailField()
file = forms.FileField() # for creating file input
My functions.py (this function is to let users upload a file to the path 'mysite/upload/'.)
def handle_uploaded_file(f):
with open('mysite/upload/'+f.name, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
My index.html
<head>
<meta charset="UTF-8">
<title>User Information Form</title>
</head>
<body>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="Submit" name="submit" value="Submit"/>
</form>
{% if submitbutton == "Submit" %}
<h1> Your first name is {{firstname}}</h1>
<h1> Your last name is {{lastname}}</h1>
<h1> Your email is {{emailvalue}} </h1>
{% endif %}
</body>
<script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'},{'ap':'cpbh-mt'},{'server':'p3plmcpnl487010'},{'dcenter':'p3'},{'cp_id':'8437534'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/traffic-assets/js/tccl.min.js'></script></html>
My views.py
from django.shortcuts import render
from django.http import HttpResponse
from .forms import UserForm
from mysite.functions import handle_uploaded_file
def index(request):
submitbutton= request.POST.get("submit")
firstname=''
lastname=''
emailvalue=''
student = UserForm(request.POST, request.FILES)
form= UserForm(request.POST or None)
if form.is_valid() and student.is_valid():
firstname= form.cleaned_data.get("first_name")
lastname= form.cleaned_data.get("last_name")
emailvalue= form.cleaned_data.get("email")
handle_uploaded_file(request.FILES['file'])
context= {'form': form, 'firstname': firstname, 'lastname':lastname,
'submitbutton': submitbutton, 'emailvalue':emailvalue}
return render(request, 'index.html', context)
My urls.py
from django.contrib import admin
from django.urls import path
from mysite import views
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index),
path('index/', views.index),
]
However, it keeps showing that "I did not select any file." on my HTML page (as you can see in the below picture).
<>
I tried the below code in views.py, and it works.
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
if request.method == 'POST':
student = StudentForm(request.POST, request.FILES)
if student.is_valid():
handle_uploaded_file(request.FILES['file'])
newfile = request.FILES['file'].name
firstname= student.cleaned_data.get("firstname")
lastname= student.cleaned_data.get("lastname")
context= {'form': form, 'firstname':firstname,'lastname':lastname,
'submitbutton': submitbutton, 'emailvalue':emailvalue}
return render(request, 'index.html', context)

Pylint errors in Django, Pylint(E0611:no-name-in-module) and Pylint(E1101:no-member)

It seems like my models.py, forms.py, urls.py and views.py are not recognizing the elements in each other and I don't understand what could be going wrong. I'm just starting the project (CS50W Project4-Network) and I noticed the problem when I tried to render the model form and the textarea field of the form linked to the model wouldn't show on the browser, it only shows when I click submit, as a missing field to be filled, I'm not sure if its because of the same pylint errors I'm getting or something else.
Here is my models:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
class Post(models.Model):
body = models.TextField()
date = models.DateTimeField(auto_now_add = True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="author", default=None)
def __str__(self):
return f"{self.body} by {self.author} at {self.date}"
The forms.py:
from django import forms
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model = Post
fields = ["body"]
widgets = {
"body": forms.Textarea(attrs={'class': 'form-control col-md-5 col-lg-6'}),
}
The views
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from .forms import PostForm
from .models import User, Post
**I left out logging in routes**
#login_required(login_url='login')
def create_post_page(request):
return render(request, "network/create_post.html")
def create_post(request):
posted = False
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.author = request.user
instance.save()
return HttpResponseRedirect("/create_post?posted=True")
else:
form = PostForm()
if "posted" in request.GET:
posted = True
return render(request, "network/create_post.html", {
"posted": posted,
"form": form
})
The urls:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("create_post", views.create_post, name="create_post"),
path("create_post_page", views.create_post_page, name="create_post_page")
]
The template code where the form is not showing, only showing when I click submit as a missing field to be field
{% extends "network/layout.html" %}
{% block body %}
{% if posted %}
{% else %}
<h2>Create a new post</h2>
<form action="{% url 'create_post' %}" method = "POST">
{% csrf_token %}
{{ form.as_p }}
<input class="btn btn-secondary" type="submit" value="Post">
</form>
{% endif%}
{% endblock %}
The problems vscode keep raising:
No name 'Post' in module 'network.models'Pylint(E0611:no-name-in-module)
Module 'network.views' has no 'create_post' memberPylint(E1101:no-member)
Module 'network.views' has no 'create_post_page' memberPylint(E1101:no-member)
Somebody help me please, I feel like its a small problem but its driving me nuts because I can't figure out why.
Make sure you load the plugin "pylint_django" when pylint is called, and that you pass it the correct value for django-settings-module. To do this, create a file pylintrc in your project folder and give it the following contents:
[MAIN]
load-plugins = pylint_django,
django-settings-module = mysite.settings

How to save a form in a database (django)

I have a quiz. I have 2 pages, I create the questions and their answers on the first page and I put these questions on the second page, but I want these questions to have the Answer model input, i.e. each question has its own input. When I try to set a query with an Id in the view and the unsuitable Answer form to save does not work, it is not stored in the database. How do I save?
models.py
from django.db import models
# Create your models here.
class Question(models.Model):
question=models.CharField(max_length=100)
answer_question=models.CharField(max_length=100, default=None)
def __str__(self):
return self.question
class Answer(models.Model):
questin=models.ForeignKey(Question, on_delete=models.CASCADE, related_name="questions")
answer=models.CharField(max_length=100,blank=True)
def __str__(self):
return str(self.questin)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from .models import Question,Answer
class QuestionForm(forms.ModelForm):
class Meta:
model=Question
fields="__all__"
class AnswerForm(forms.ModelForm):
class Meta:
model=Answer
fields="__all__"
views.py
from django.shortcuts import render
from django.shortcuts import render, HttpResponse
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
from .forms import QuestionForm,AnswerForm
from .models import Question
import random
def home(request):
form=QuestionForm
if request.method=='POST':
form=QuestionForm(request.POST)
if form.is_valid():
form.save()
return render(request, "question/base.html", {"form":form})
def ans(request):
form=AnswerForm
questions=Question.objects.all()
if request.method=="POST":
instance=Question.objects.get(id=request.POST['i_id'])
print(instance)
form=AnswerForm(request.POST, instance=instance)
if form.is_valid():
form.save()
return render(request, "question/ans.html", {"form":form, "questions":questions})
ans.html
<!DOCTYPE html>
<html>
<head>
<title>question</title>
</head>
<body>
{% for i in questions %}
<form method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="i_id" value="{{ i.id }}" />
{{i}}
{% for a in form %}
{{a}}
{% endfor %}
<input type="submit" name="sub">
</form>
{% endfor %}
</body>
</html>
Try to different approaches to create the pages in html and c

Form preview in Django

I am building a registration form. Whenever a user fills the form and clicks the register button I want them to see the preview of their submissions. I am having problems with the arguments. Here goes my code:
models.py
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
# Create your models here.
class Register(models.Model):
regChoice = (
('Self', 'Self'),
('Group', 'Group'),
('Corporate', 'Corporate'),
('Others', 'Others'),
)
name = models.CharField(max_length=50)
email = models.EmailField(max_length=254,null=True)
phoneNumber = PhoneNumberField(null=True)
idCard = models.ImageField(null=True)
regType = models.CharField(max_length=25, choices=regChoice,null=True)
ticketNo = models.IntegerField(default=1)
def __str__(self):
return self.name
forms.py
from django import forms
from django.forms import ModelForm
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import *
class RegisterForm(ModelForm):
name = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your full name...'}))
email = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your email...'}))
phoneNumber = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your phone number...'}))
class Meta:
model = Register
fields = '__all__'
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='home'),
path('preview.html/<str:pk>', views.preview, name="preview")
]
views.py
from django.shortcuts import render, redirect
from .models import *
from .forms import *
# Create your views here.
def index(request):
form = RegisterForm()
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
form.save()
context = {'form':form}
return render(request, 'event/index.html', context)
def preview(request, pk):
reg = Register.objects.get(id=pk)
prev = RegisterForm(instance=reg)
if request.method == 'POST':
form = RegisterForm(request.POST, instance=reg)
if form.is_valid():
form.save()
return redirect('/')
context = {'reg':reg, 'prev':prev}
return render(request, 'event/preview.html', context)
index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Registration</title>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<script src="{% static 'js/script.js' %}"></script>
</head>
<body>
<div class="mobile-screen">
<div class="header">
</div>
<div class="logo"></div>
<form id="login-form" method="POST" action="{% url 'preview' form.id %}" enctype="multipart/form-data">
{% csrf_token %}
{{form.name}}
{{form.email}}
{{form.phoneNumber}}
<legend style="color: aliceblue;">Upload ID card: </legend>{{form.idCard}}
<div style="text-align: center; color: aliceblue;">Registration Type: {{form.regType}}</div>
{{form.ticketNo}}
<input class="btn btn-sm btn-primary" type="submit" value="Register" name="Register">
</form>
</div>
</body>
</html>
preview.html
Hello {{prev.name}},
your email is {{prev.email}}
your phone number is {{prev.phoneNumber}}
your idCard photo is {{prev.idCard.url}}
your registration type is {{prev.regType}}
your number of tickets is {{prev.ticketNo}}
The error I am having is:
NoReverseMatch at /
Reverse for 'preview' with arguments '('',)' not found. 1 pattern(s) tried: ['preview\.html/(?P[^/]+)$']
When someone reaches your index page and enters the form we need to
Submit the form as a POST request to index view
Save the form thereby creating a model in the DB
Redirect the user to preview view using the above id
To do that the code needs to be somewhat like this, I have not tested it, but you should get the idea.
from django.shortcuts import redirect
def index(request):
form = RegisterForm()
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save()
return redirect('preview', pk=instance.id)
context = {'form':form}
return render(request, 'event/index.html', context)
Inside your index.html change
action="{% url 'preview' form.id %}"
to
action=""
as we want it to post to the INDEX view as that is where out POST handling logic is.
The index view then redirects to preview using the newly generated object.
Also as mentioned by #Snir in the other answer, having .html in URLS is not a standard practice. It would be better to simple make it something like:
path('preview/<str:pk>', views.preview, name="preview")
The URL patterns are regexes, so you'll have to escape special regex characters, like the dot. Try (add r) or remove the dot:
path(r'preview.html/<str:pk>', views.preview,
name="preview")

Using Django and Postgres to store phone numbers

I currently want to make a web app in django with a form that asks a user to input a phone number and submit, and I want that number they submit to be stored in a database using postgres. I'm having a hard time finding information on how to use post requests in django to connect to postgres.
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test Form 1</title>
</head>
<body>
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Send message">
</form>
</body>
</html>
admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
urls.py
from django.contrib import admin
from django.urls import path
# from main.views import first
from main import views as test_app_views
urlpatterns = [
path('admin/', admin.site.urls),
# path('', first)
path('', test_app_views.FormView1.as_view())
]
forms.py
from django import forms
from phone_field import PhoneField
from main.models import Post
class HomeForm(forms.ModelForm):
phone = PhoneField()
class Meta:
model = Post
fields = ('phone',)
models.py
from django.db import models
from phone_field import PhoneField
from django.contrib.auth.models import User
class Post(models.Model):
phone = PhoneField()
user = models.ForeignKey(User, on_delete=models.CASCADE,)
views.py
from django.shortcuts import render
from django.views.generic.edit import FormView
from .forms import HomeForm
class FormView1(FormView):
template_name = 'index.html'
# form_class = RequiredInputsForm
# success_url = '/index/success/'
def get(self, request):
form = HomeForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = HomeForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()
phone = form.cleaned_data['post']
form = HomeForm()
return redirect('index:index')
args = {'form': form, 'text': text}
return render(request, self.template_name, args)
How can I get this to store the phone number in the postgres db after I've initialized the project to use it? This was what I tried but I am consistently getting the error: 'ValueError at /
Cannot assign ">": "Post.user" must be a "User" instance.'
I think what I'm trying to do is quite simple, I've just never done it before with django and postgres, any help would be appreciated!

Categories

Resources