I am having troubles with submitting the this form. I could submit the form from the admin dashboard but not from the template. What could I be doing wrong?
models.py file:
from teamprofile.models import TeamProfile
from django.utils import timezone
from competition.models import CompetitionProfile
from datetime import datetime
from django.contrib.auth.models import User
class MatchProfile(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
competition = models.ManyToManyField(CompetitionProfile)
home_team = models.ForeignKey(TeamProfile, on_delete=models.CASCADE, related_name = 'home_team')
away_team = models.ForeignKey(TeamProfile, on_delete=models.CASCADE, related_name = 'away_team')
# start_time = models.DateField(blank=True, null=True)
def __str__(self):
return "{} vs {}".format(self.home_team, self.away_team)
forms.py file:
from .models import MatchProfile
class CreateMatchForm(forms.ModelForm):
class Meta():
model = MatchProfile
fields = ('competition', 'home_team', 'away_team')
widgets = {
'competition': forms.Select(attrs={'class': 'uk-select'}),
'home_team': forms.Select(attrs={'class': 'uk-select' }),
'away_team': forms.Select(attrs={'class': 'uk-select' }),
# 'start_time': forms.SelectDateWidget(),
}
views.py file:
from .forms import CreateMatchForm
from .models import MatchProfile
class MatchProfileCreateView(CreateView):
model = MatchProfile
success_url = reverse_lazy('home')
form_class = CreateMatchForm
def form_valid(self, form):
form.instance.owner = self.request.user
return super(MatchProfileCreateView, self).form_valid(form)
.html file:
<form class="uk-child-width-1-2#s uk-grid-small p-4" uk-grid method="POST">
<div> {% csrf_token %}
<h5 class="uk-text-bold mb-2"> Competiton Name </h5>
{{ form.competition }}
<!-- <input type="text" class="uk-input" placeholder="Your name"> -->
</div>
<div>
<h5 class="uk-text-bold mb-2"> Home Teams </h5>
{{ form.home_team }}
<!-- <input type="text" class="uk-input" placeholder="Your seccond"> -->
</div>
<div>
<h5 class="uk-text-bold mb-2"> Away Team </h5>
{{ form.away_team }}
<!-- <input type="text" class="uk-input" placeholder="eliedaniels#gmail.com"> -->
</div>
<!-- <div>
<h5 class="uk-text-bold mb-2"> Organizer Contact</h5>
{{ form.organizer_contact }} -->
<!-- <input type="text" class="uk-input" placeholder="+1 555 623 568 ">
</div> -->
<div class="uk-flex uk-flex-right p-4">
<button class="button soft-primary mr-2">Cancel</button>
<button type="submit" class="button primary">Create Match</button>
</div>
</form>
I am definitely doing something the wrong way but I can't seem to figure it out. Other forms built with same method and template seems to be working.
My terminal would show that a POST request was made yet it still doesn't work
I would find that error was from forms.py:
Turns out the POST request send a field input different from what was declared on the model.
I changed the
'competition': forms.Select(attrs={'class': 'uk-select'}),.
to
'competition': forms.SelectMultiple(attrs={'class': 'uk-select'}),
Difference being forms.SelectMultiple as the model was a ManyToManyField.
Related
I am very new to web development and specifically using Django Framework.
I am trying to find a clean, efficient and non external package dependant implementation for an autocomplete-datalist form field inside a Generic class based CreateView template in Django.
I have found numerous resources on various implementations, but most of them depend on external packages(autocomplete-light, jqueryCDN, etc.) and none of it is based on a class based generic CreateView.
I have been experimenting and I have managed to make the autocomplete-datalist work in a way but I am stuck in a very simple problem when I try to post my form with the data from the datalist element.
I get a validation error:
"city_name: This field is required"
I also noticed that the city object queried from the database inside the datalist has also the id of the city_name
models.py
from django.db import models
class City(models.Model):
name = models.CharField(max_length=50)
class Meta:
verbose_name_plural = "cities"
ordering = ['name']
def __str__(self):
return self.name
class Person(models.Model):
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=40)
address = models.CharField(max_length=150)
city_name = models.ForeignKey(City, on_delete=models.CASCADE)
def __str__(self):
return f'{self.first_name} {self.last_name}'
views.py
from django.views.generic import ListView, CreateView
from django.contrib.messages.views import SuccessMessageMixin
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Person, City
from .forms import PersonForm
# Create your views here.
class PersonList(LoginRequiredMixin, ListView):
model = Person
template_name = "home.html"
paginate_by = 20
login_url = "/login/"
redirect_field_name = 'redirect_to'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
class PersonCreate(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = Person
template_name = "testform.html"
login_url = "/login/"
form_class = PersonForm
success_url = 'testapp/add/'
success_message = 'Person registered successfully!'
redirect_field_name = 'redirect_to'
forms.py
from django import forms
from .models import Person, City
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ["first_name", "last_name", "address", "city_name"]
testform.html
{% extends 'home.html' %}
{% load static %}
{% block content %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-success alert-dismissible fade show" role="alert">
<span style="font-size: 18px;padding: 1mm"><i class="fa-solid fa-circle-check"></i></span>{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endif %}
<form method="POST">
{% csrf_token %}
<div class="mb-3">
<label for="first_name charfield" class="form-label"> First Name</label>
{{form.first_name}}
</div>
<div class="mb-3">
<label for="last_name charfield" class="form-label">Last Name</label>
{{form.last_name}}
</div>
<div class="mb-3">
<label for="address charfield" class="form-label">Address</label>
{{form.address}}
</div>
<div class="mb-3">
<label for="city_name datalist" class="form-label">City Name</label>
<input type="text" list="cities" class="form-control">
<datalist id="cities">
{% for city in form.city_name %}
<option>{{ city }}</option>
{% endfor %}
</datalist>
</div>
<button class="btn btn-outline-primary" type="submit">Submit</button>
</form>
{{form.errors}}
{% endblock %}
Result:
I believe it is a necessary feature for all modern web applications to have this kind of functionality within their database query-autocomplete form fields system. It is a pity that although Django provides this feature for the AdminModels through its autocomplete_fields attribute, it makes it so hard to implement on Generic Class Based Views on the actual application models.
How can I approach this issue, and is there a efficient and more optimized way to implement it?
If you don't want a field required you can set the attribute blank=True in the model class. A question I have is why would you want to have a Foreignkey to just a city name. Or are you trying to use the a list of cities to populate the drop down? In that case the Foreign Key is definitely not the answer.
I am trying to display my stat update form in my Django template, however it isn't displaying. My stats below show up correctly, just not the form.
{{ stats.user }} | {{ stats.weight }} | {{ stats.date }}
Template:
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 text-center">
<h1>My Health</h1>
</div>
</div>
</div>
<div class="container-fluid">
<div class="col-auto text-center p-3 form-group">
<form method="post" style="margin-top: 1.3em;">
{{ update_form }}
{% csrf_token %}
<button type="submit" class="btn btn-signup btn-lg">Submit</button>
</form>
</div>
<div class="row justify-content-center">
<div class="col-auto text-center p-3">
<p class="text-center"> {{ stats.user }} | {{ stats.weight }} | {{ stats.date }} </p>
</div>
</div>
</div>
{% endblock content %}
forms.py:
class StatUpdateForm(forms.Form):
class Meta:
model = Stats
fields = ('user', 'weight', 'date')
models.py:
class Stats(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(auto_now=True)
weight = models.DecimalField(max_digits=5, decimal_places=2)
class Meta:
db_table = 'health_stats'
ordering = ['-date']
def __str__(self):
return f"You currently weigh {self.weight}, {self.user}"
views.py:
from django.shortcuts import render
from .models import Stats
from .forms import StatUpdateForm
from django.views import generic, View
from django.shortcuts import get_object_or_404
# from django.contrib.auth import authenticate
# from django.core.exceptions import ValidationError
# from .forms import RegistrationForm, LoginForm
def home(request):
return render(request, 'home.html')
class MyHealth(View):
def get(self, request, *args, **kwargs):
stats = Stats
context = {
'stats': stats,
"update_form": StatUpdateForm(),
'user': stats.user,
'weight': stats.weight,
'date': stats.date,
}
return render(request, 'MyHealth.html', context)
I've tried redefining the form in my views.py, but I'm unsure why it isn't pulling through, as the other parts of the context are.
Any help would be appreciated!
In the form, since you are using a model, you must extend from forms.ModelForm instead forms.Form, try to change that line in the forms.py
class StatUpdateForm(forms.ModelForm): # extends from forms.ModelForm
class Meta:
model = Stats
fields = ('user', 'weight', 'date')
I assume the form fields are rendering and the fields just aren't loaded with the correct values.
do this: StatUpdateForm(instance=stats) to make it an edit form
I am building a portfolio and i am just learning django i tried to bring data from About in sql and since i have only single piece of data i dont need for loop so i tried putting it directly but is seems i cannot do that. Any suggestion on how i can do it
<section id="about">
<div class="container">
<div class="about-large d-none d-lg-block text-uppercase">About</div>
<div class="about-me row mt-5">
<div class="my-image col-md-5">
<img src="{{ about.image }}" />
</div>
<div class="my-description col-md-6">
<h3>About Me</h3>
<h4>I am {{about.name}}</h4>
<p>{{ about.description }}</p>
<p>{{ about.description_two }}</p>
<div class="cv-hire d-flex flex-start">
<button type="button" class="btn btn-dark font-weight-bold">
Download <i class="fas fa-download pl-2"></i>
</button>
</div>
</div>
</div>
</div>
</section>
My Views .py
from django.shortcuts import render
from django.views.generic import TemplateView
from .models import *
class HomeTemplateView(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['about'] = About.objects.first()
context['services'] = Service.objects.all()
context['works'] = RecentWork.objects.all()
return context
My models.py
from django.db import models
class About(models.Model):
image = models.ImageField(upload_to="static/img")
name = models.CharField(max_length=100,verbose_name="My Name")
description = models.CharField(max_length=500, verbose_name="Description")
description_two = models.CharField(max_length=500, verbose_name="Description", blank=True)
cv = models.FileField(upload_to="static/document")
class Meta:
verbose_name = "About Me"
verbose_name_plural = "About Me"
def __str__(self):
return "About Me"
I'd make some checks:
What returns About.objects.first() in Django shell?
Make template with {{ about.cv }} only to avoid other influences.
Then I can see if expected data exist and what incomes to template.
I am new to django, I created my custom user(auth_user) model. I need to create student registration form using custom user model according to my custom object
I have two models Title, User like this:
from django.db import models
#from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
from django.db.models.signals import post_save
from django.contrib.auth.models import AbstractUser
class Title(models.Model):
value = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return self.value
class Meta:
db_table = 'title'
class User(AbstractUser):
title = models.ForeignKey(Title, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
db_table = 'user'
settings.py:
AUTH_USER_MODEL = 'student.User'
Here i have ForeignKey title field and User default fields first_name, last_name, email,password
My forms.py:
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from django.core import validators
from student.models import User
from student.models import Title
class StudentRegistrationForm(forms.Form):
filenumber = forms.CharField(label='Filenumber', max_length=45)
class StudentNewRegistrationForm(forms.ModelForm):
title = forms.CharField(required=True)
username = forms.CharField(required=True)
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
email = forms.EmailField(required=True)
password1 = forms.CharField(required=True)
password2 = forms.CharField(required=True)
def __init__(self, *args, **kwargs):
super(StudentNewRegistrationForm, self).__init__(*args, **kwargs)
self.fields['title'] = forms.ModelChoiceField(queryset=Title.objects.all(), empty_label='Choose a title',required=False)
class Meta:
model = User
fields = ['title','username', 'first_name', 'last_name','email' 'password1', 'password2']
def save(self, commit=True):
user = super(StudentNewRegistrationForm, self).save(commit=False)
user.username = self.cleaned_data['username']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
user.title = self.cleaned_data['title']
user.password1 = user.set_password(self.cleaned_data['password1'])
user.password2 = user.set_password(self.cleaned_data['password2'])
if commit:
user.save()
return user
Here i have api response like below:
{"candidate":{"firstname":"Testuser","lastname":"test","salutation":10000,"email":"testing#gmail.com","username":"test"}}
This response coming form studentregistrationview:
from django.shortcuts import render, redirect
from django.urls import reverse
from student.forms import RegistrationForm
from django.contrib.auth import get_user_model
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
from .forms import StudentRegistrationForm, StudentNewRegistrationForm
import requests
from django.http import JsonResponse
from django.http import HttpResponse
#from django.contrib.auth import get_user_model
from student.models import User
from student.models import Title
import json
import urllib
from django.conf import settings
from django.contrib import messages
def studentregistration(request):
form = StudentRegistrationForm()
if request.method == 'POST':
form = StudentRegistrationForm(request.POST)
if form.is_valid():
data = form.cleaned_data
inputdata = data.get('filenumber')
url = 'https://myapiurl/' + inputdata
result = requests.get(url)
finalresult = result.json()
studentapires = {'studentres': finalresult}
request.session['studentapires'] = studentapires
return redirect('/student/studentnewregistration')
else:
form = StudentRegistrationForm()
return render(request, 'student/studentregister.html', {'form': form})
I am creating new user object like below and i tried to persist object, here issue object is not persisting to user table
student_new_registration view i tried to create new User object like below
student_new_registration.py:
def student_new_registration(request):
studentapires = request.session.get('studentapires', None)
jsonresult = studentapires['studentres']['candidate']
user = User()
if jsonresult['salutation'] == 100000000:
salutation = 'Mister'
elif jsonresult['salutation'] == 100000002:
salutation = 'Madam'
title = Title.objects.get(value=salutation)
user.title = title
user.first_name = jsonresult['firstname']
user.last_name = jsonresult['lastname']
user.email = jsonresult['email']
user.username = jsonresult['username']
if request.method == 'POST':
form = StudentNewRegistrationForm(request.POST, instance=user)
if form.is_valid():
form.save()
return HttpResponse("Registration Completed")
return HttpResponse("Please Check Your Registration Form")
else:
form = StudentNewRegistrationForm(instance=user)
args = {'form': form}
return render(request, 'student/studentnewregistrationform.html', args)
Error:
full_clean() missing 1 required positional argument: 'self', form is not submitting (means form not going inside form.is_valid())
studentnewregistrationform.html:
{% extends 'base.html' %}
{% block head %}
<title>Student Profile Form</title>
{% endblock %}
{% block body %}
<div class="container">
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-sm-4">
<h3> Student Profile Form</h3>
</div>
</div>
<br>
<div class="row">
<div class="col-sm-2">{{ form.title.label }}</div>
<div class="col-sm-3">{{ form.title }}</div>
<div class="col-sm-4">{{ form.title.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2">{{ form.first_name.label }}</div>
<div class="col-sm-3">{{ form.first_name }}</div>
<div class="col-sm-4">{{ form.first_name.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2">{{ form.last_name.label }}</div>
<div class="col-sm-3">{{ form.last_name }}</div>
<div class="col-sm-4">{{ form.last_name.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2">{{ form.email.label }}</div>
<div class="col-sm-3">{{ form.email }}</div>
<div class="col-sm-4">{{ form.email.errors }}</div>
</div>
<br>
<br>
<div class="row">
<div class="col-sm-2">{{ form.username.label }}</div>
<div class="col-sm-3">{{ form.username }}</div>
<div class="col-sm-4">{{ form.username.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2"><label for="{{ form.password1.label }}">Password</label></div>
<div class="col-sm-3">{{ form.password1 }}</div>
<div class="col-sm-4">{{ form.password1.errors }}</div>
</div>
<br>
<div class="row">
<div class="col-sm-2"><label for="{{ form.password2.id_for_label }}">ConfirmPassword</label></div>
<div class="col-sm-3">{{ form.password2 }}</div>
<div class="col-sm-4">{{ form.password2.errors }}</div>
</div>
<br><br>
<div class="row">
<div class="col-sm-2 col-sm-offset-2"> <input type="submit" name="submit" value="Submit" class="btn btn-primary"/></div>
<div class="col-sm-2"></div>
</div>
</form>
</div>
{% endblock %}
here issue is i am able to render all fields to registration form but i am not able to persist data and while persisting custom object i am getting this error
Manager isn't available; 'auth.User' has been swapped for 'student.User'
please help me any one, Thanks in advance...
You need to change User model inside your views.py file and in any other files where you are using User class. To new model. For this try to add following import:
from django.contrib.auth import get_user_model
User = get_user_model()
Instead of
from django.contrib.auth.models import User
I have a form in my site to get a report about some "collective payment". It has 3 main field: Value, date of payment and who paid.
The field "who paid" is a table containing the name of all users and a checkbox.
Currently I'm looping over all users, adding their full names to the table with a single checkbox. But I don't know how to get this data in my form associating it with each user name (just the text).
How can I get multiple BooleanFields in my form ? Is there a way of associate each BooleanField with an user's name?
model.py
from django.db import models
#created_date attibute needs it
from django.utils import timezone
# This Model is a super class "Financial Transaction"
class GroupTransaction(models.Model):
name = models.CharField(max_length=257, default='')
who_paid = models.CharField(max_length=257, default='')
value = models.DecimalField(max_digits=6, decimal_places=2)
justification = models.CharField(max_length=257, default='')
created_date = models.DateTimeField(default=timezone.now)
date = models.CharField(max_length=257, default='')
receipt = models.FileField(upload_to='comprovantes', blank=True, null=True)
its_type = models.CharField(max_length=257, default='')
def __str__(self):
#INCOMPLETOreturn "%s fez a movimentação financeira de %d para %s no dia " % (self.name, self.restaurant)
return "%s - %s" % (self.name , self.who_paid)
view.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from deposit.forms import DepositForm,MonthlyDepositForm
from django.contrib.auth.models import User
# Create your views here.
#login_required
def deposito(request):
if request.method == 'POST':
form = DepositForm(request.POST, request.FILES)
if form.is_valid():
form.save()
HttpResponseRedirect('/historico/')
else:
print (str(form.errors.as_data()))
else:
form = DepositForm()
groupForm = MonthlyDepositForm()
return render(request, 'shell/app_shell.html', {
'is_deposit' : True,
'title' : 'Deposit',
'transaction' : form,
'groupTransaction' : groupForm,
'users': User.objects.all()
})
form.py
class MonthlyDepositForm(forms.ModelForm):
value = forms.DecimalField()
date = forms.CharField(widget=forms.TextInput(attrs={
'class':'datepicker picker__input',
'readonly':'',
'tabindex':'54',
'aria-haspopup':'True',
'aria-expanded':'false',
'aria-readonly':'false',
'aria-owns':'birthdate_root'
}))
who_paid = forms.BooleanField()
its_type = forms.CharField(widget=forms.HiddenInput(attrs={'readonly':True}),
initial='Deposito Mensal')
class Meta:
model = GroupTransaction
fields = ('value', 'date','who_paid','its_type')
template.html:
<form class="col s12">
{% csrf_token %}
{{ groupTransaction.its_type }}
<div class="row"></div>
<!-- Nome do evento -->
<div class="row">
<div class="input-field col s6">
<!-- <input id="nome_evento" type="number" value="10" step="any" min="0.05" max="400" class="validate" required> -->
{{ groupTransaction.value }}
<label for="nome_evento">Value</label>
</div>
<div class="input-field col s6">
<!-- <input type="text" class="datepicker picker__input" readonly="" tabindex="54" aria-haspopup="true" aria-expanded="false" aria-readonly="false" aria-owns="birthdate_root" required> -->
{{ groupTransaction.date }}
<label for="data-mensal" data-error="Data inválida">Date</label>
</div>
</div>
<!-- Petianos que irão para o evento -->
<table class="striped">
<thead>
<!-- Cabeçalho tabela -->
<tr>
<th>Who Paid</th>
<th>
<div class="switch">
<b class="center-align">Default</b>
<label>
<input type="checkbox">
<span class="lever"></span>
</label>
</div>
</th>
</tr>
<!-- ============= -->
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.get_full_name }}</td>
<td>
<div class="switch">
<label>
<!-- <input type="checkbox"> -->
{{ groupTransaction.who_paid }}
<span class="lever"></span>
</label>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row"></div>
<div class="row"></div>
<!-- Botão de registrar saque (submit) -->
<div class="row">
<button class="btn waves-effect waves-light col s6 m3 offset-s6 offset-m9 blue" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</div>
</form>
How the form is:
You need to make who_paid a ManyToManyField(User). Then in the form you can set its widget like this:
class Meta:
model = GroupTransaction
fields = ('value', 'date','who_paid','its_type')
widgets = {
'who_paid': forms.CheckboxSelectMultiple(),
}
That will give you the right structure. Then you can render it manually if you want to change the display.