Unable to save the data from checkboxes and radiobuttons using modelForm - python

model.py
class FormData(models.Model):
email = models.EmailField()
full_name = models.CharField(max_length=120)
text_area = models.CharField(max_length=250)
radio_buttons = models.CharField(max_length=25)
check_boxes = models.CharField(max_length=10)
def __unicode__(self):
return self.email
forms.py
class MyModelForm(forms.ModelForm):
class Meta:
model = FormData
fields = ['text_area','email','full_name']
widgets = {
'text_area': Textarea(attrs={'cols': 50, 'rows': 10}),
}
TYPE_CHOICES = [('s', 'small'),('m', 'medium'),('b', 'big')]
check_boxes = forms.MultipleChoiceField(choices=TYPE_CHOICES, widget=forms.CheckboxSelectMultiple())
CHOICES = [(1, 'One'),(2, 'Two'),(3, 'Three'),(4, 'Four')]
radio_buttons = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect())
views.py
def home(request):
title = 'Welcome'
form = MyModelForm(request.POST)
context = {"title":title,"form":form}
if form.is_valid():
instance = form.save(commit=False)
instance.save()
context = {"title":"Thank You!"}
return render(request,"home.html",context)
home.html
<h1>{{title}}</h1>
<form method='POST' action=''>{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Submit">
</form>
The problem is that I can't seem to understand how to save the data from the checkboxes and the radiobuttons. The form gets submitted successfully but when I look in the database the field of check_boxes is empty and the radio_buttons field shows a value "False" while I need my manual values as defined in the CHOICES list.

You have added two extra fields in your form which you have not mentioned in fields. Change your form like this.
class MyModelForm(forms.ModelForm):
class Meta:
model = FormData
fields = ['text_area','email','full_name', 'check_boxes', 'radio_buttons']
widgets = {
'text_area': Textarea(attrs={'cols': 50, 'rows': 10}),
}
TYPE_CHOICES = [('s', 'small'),('m', 'medium'),('b', 'big')]
check_boxes = forms.MultipleChoiceField(choices=TYPE_CHOICES, widget=forms.CheckboxSelectMultiple())
CHOICES = [(1, 'One'),(2, 'Two'),(3, 'Three'),(4, 'Four')]
radio_buttons = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect())

Related

Django Model Multi Select form not rendering properly

I am trying to display all the categories to appear as a list that I can click and select from, just an exact replica of what I have in my admin panel, but it still display's as a list that isn't clickable.
forms.py
class ProfileEditForm(forms.ModelForm):
"""
Form for updating Profile data
"""
class Meta:
model = Profile
fields = [
"first_name",
"last_name",
"about_me",
"profile_image",
"username",
"email",
"categories",
]
first_name = forms.CharField(label="First Name", max_length=63, required=False)
last_name = forms.CharField(label="Last Name", max_length=63, required=False)
about_me = forms.CharField(label="About Me", max_length=511, required=False)
email = forms.EmailField(label="Email", disabled=True)
username = forms.CharField(label="Username", disabled=True)
profile_image = forms.ImageField(required=False)
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
)
profile.models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
first_name = models.CharField(max_length=63, blank=False)
last_name = models.CharField(max_length=63, blank=False)
about_me = models.CharField(max_length=511, blank=True)
categories = models.ManyToManyField(
Category, related_name="user_categories", symmetrical=False
)
categories.models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=63)
created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
last_modified = models.DateTimeField(auto_now=True, blank=True, null=True)
def __str__(self):
return self.name
def __unicode__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
settings.html
<div class='row'>
<div class="col s12 m6">
{{form.categories.errors}}
{{form.categories.label_tag}}
{{form.categories}}
</div>
</div>
What I hope to achieve
What I get
You need to create the form itself:
<form method='post'>
</form>
And print each field on a new line:
{{ form.as_p }}
is a security check.
{% csrf_token %}
In the view, I left get_context_data. In it, you can add values ​​to the context, for example, like this:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['rubrics'] = Car.objects.all()
Replace bboard with the name of the folder where your templates are placed.
I have this: templates/bboard which are in the application folder.
In the view for the form, the CreateView class is used, in which: template_name - the name of the template for displaying the page, form_class - the form class is indicated, success_url - where to return in case of successful saving of the form (in this case, this is the same page with the form), get_context_data - the template context (you can print it out and see what's inside).
And if your model has fields: first_name, last_name, about_me, email, username, profile_image, then it is enough that you have specified the fields variable in the class Meta class. You don't need to re-create them in the form.
template_name = 'bboard/tam_form.html'#bboard replace with your prefix
Templates
<form method='post'>
{{form.categories.errors}}
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value='adding'>
</form>
views.py
from .forms import *
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
class Profile(CreateView):
template_name = 'bboard/settings.html'#bboard replace with your prefix
form_class = ProfileEditForm
success_url = reverse_lazy('test')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('test/', Profile.as_view(), name='test'),
]
Update 13.11.2022
This is how my form looks like when I go to the address:
http://localhost:8000/test/
But the form is not submitted. I don't have much experience with this. I can assume that forms.ModelForm expects that the model has such fields, because if you delete the lines with email, username, profile_image and also remove them from the fields and add 'user' to the field, then the data will be saved in the database (checked).
As I said earlier, if the fields are declared in fields, then you do not need to define them again (if you leave them, the form will also be saved). This is what the form class looks like:
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = [
'user',
'first_name',
'last_name',
'about_me',
'categories',
]
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
)

Why is the form not shown on the website?

I have a feedback form and it should be located on the main page along with other models. But alas, for some reason it refers to a non-existent template. And thus it is not shown on the site, although the model itself is present in the admin panel.
Please help me figure it out.
I was trying many ways to figure out it, but theres nothing
views.py
class MainDetail(CreateView):
success_url = reverse_lazy('success_page')
form_class = ContactForm
def get(self, request, **kwargs):
search_query = request.GET.get('search', )
model_2 = Jobs.objects.order_by()
form = ContactForm(request.POST)
portfolio = Portfolio.objects.prefetch_related('image')
ctx = {
'jobs':model_2,
'portfolio': portfolio
}
form = ContactForm(request.POST)
if form.is_valid():
form.save()
return render(request, 'homepage.html', ctx)
def form_valid(self, form):
# Формируем сообщение для отправки
data = form.data
subject = f'Сообщение от {data["first_name"]} {data["last_name"]},Тема: ORDER {data["phone"]}'
email(subject, data['message'])
return super().form_valid(form)
model.py
class Contact(models.Model):
first_name = models.CharField ('Name', max_length=25)
last_name = models.CharField('Last Name', max_length=30)
phone = models.EmailField ('Phone', max_length=15)
message = models.TextField (max_length=400)
class Meta:
verbose_name= 'Feedback'
verbose_name_plural = 'Feedsbacks'
def __str__(self):
class Meta:
verbose_name= 'Feedback'
verbose_name_plural = 'Feedsbacks'
def __str__(self):
return self.first_name
forms.py
class ContactForm(ModelForm):
class Meta:
model = Contact
fields = ['first_name', 'last_name', 'phone', 'message']
widgets = {
'first_name': forms.TextInput (
attrs={'placeholder':'Name'}
),
'last_name': forms.TextInput(
attrs={'placeholder': 'Wash'}
),
'phone': forms.TextInput(
attrs={'placeholder': '+7 (123) 45-67-89'}
),
'message': Textarea(
attrs={
'placeholder': 'Message',
"rows":6,
"cols": 25
}
)
}
html
<aside class="postcard">
<form class="form" method="POST">
<p>Order</p>
{% csrf_token %}
{{ form.as_p }}
<div class="form-group">
<input type="submit" value="Send">
</div>
</form>
</aside>
Thanks for any help
Here it is the solution to all the troubles
class MainDetail(CreateView):
model = Jobs
model_2 = Portfolio
model_3 = Contact
template_name = 'homepage.html'
success_url = reverse_lazy('success_page')
form_class = ContactForm
def get_context_data(self, **kwargs):
context = super(MainDetail, self).get_context_data(**kwargs)
context['first_form'] = ContactForm (self.request.POST)
context['jobs'] = Jobs.objects.order_by()
context['portfolio'] = Portfolio.objects.prefetch_related('image')
return context

Form not being saved in Database Django

I have created a form for a Post. The form loads and when I enter all the value and try to submit the form, it gets refreshed but the database is not updated.
Here is my Post Model:
class Post(models.Model):
no_people = models.IntegerField()
no_days = models.IntegerField()
tour_date = models.CharField(max_length=200, blank=True)
Gender_types = (
('M', 'Male'),
('F', 'Female'),
('O', 'Others'),
)
Gender_prefer = models.CharField(max_length=1, choices=Gender_types)
location = models.CharField(max_length=200, blank=True)
pic_location = models.ImageField(blank=True, upload_to="posts/")
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
detail = models.TextField()
liked = models.ManyToManyField(Yatru, blank=True, related_name= 'likes')
author = models.ForeignKey(Yatru, on_delete=models.CASCADE, related_name = 'posts',null=True)
def __str__(self):
return str(self.location)
def no_likes(self):
return self.liked.all().count()
class Meta:
ordering = ('-created',)
def save(self, *args, **kwargs):
self.location = self.location.upper()
return super(Post, self).save(*args, **kwargs)
LIKE_CHOICES = (
('Like', 'Like'),
('Unlike', 'Unlike'),
)
Here is the form.py:
from django import forms
from .models import Post
class PostModelForm(forms.ModelForm):
class Meta:
model = Post
fields = ('no_people','no_days','tour_date', 'Gender_prefer','location','detail')
Here is the views.py:
def post_add(request):
user = request.user
profile = Yatru.objects.get(user=user)
form = PostModelForm(request.POST or None, request.FILES or None, instance=profile)
if request.method == 'POST':
if form.is_valid():
newpost=form.save(commit=False)
newpost.user=request.user
newpost.save()
return render(request, 'posts/my_post.html',{'form': form})
This is the HTML file:
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<button type='submit'>Submit </button>
</form>
Hi please follow instructions:
First insert "author" field in field tuple of model form
In your post_add view change below line
newpost.author=request.user

create a distinct model option in a dropdown using django

I have created this application but the problem I face now is one that has kept me up all night. I want users to be able to see and select only their own categories when they want to create a post. This is part of my codes and additional codes would be provided on request
category model
class Category(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1,related_name='categories_created')
name = models.CharField(max_length = 120)
slug = models.SlugField(unique= True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
post model
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1,related_name='posts_created') #blank=True, null=True)
title = models.CharField(max_length = 120)
slug = models.SlugField(unique= True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category_created', null= True)
addition codes would be provided immediately on request. Thanks
View.py in post app
def create(request):
if not request.user.is_authenticated():
messages.error(request, "Kindly confirm Your mail")
#or raise Http404
form = PostForm(request.POST or None, request.FILES or None)
user = request.user
categories = Category.objects.filter(category_created__user=user).distinct()
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
create_action(request.user, 'Posts', instance)
messages.success(request, "Post created")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
}
template = 'create.html'
return render(request,template,context)
Form
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [
"title",
"content",
"category",
]
html
{% if form %}
<form method="POST" action="" enctype="multipart/form-data">{% csrf_token %}
{{ form|crispy|safe }}
<input type="submit" name="submit" value="Publish">
</form>
{% endif %}
What you need to do is well-described here. Basically, you are using ModelForm which generates the form from your model. Your model doesn't know anything about filtering by user, so you will need to explicitly add a QuerySet to your form that only shows the desired categories. Change your "categories = ..." line to something like:
form.category.queryset = Category.objects.filter(user=user)
form.fields['category'].queryset = Category.objects.filter(user=user)</strike>

filter choices from Django models using ModelForm

I have to send some data to my database where I have a phone object. For this I need to select the desired phone number and insert the desired information to the database.
A requirement is to display the phone numbers that belongs to the current login user.
I use Django model named Phone and a modelForm named phoneForm.
class Phone(models.Model):
user = models.ForeignKey(User)
phone_num = models.ForeignKey(Sim, null=True)
imei = models.CharField(max_length=30, primary_key=True)
num_calls = models.CharField(max_length=20, null=True, blank=True)
time_btwn_calls = models.CharField(max_length=20, null=True, blank=True)
psap = models.CharField(max_length=30, null=True, blank=True)
class Sim(models.Model):
phone_num = models.CharField(max_length=30, primary_key=True)
pin = models.CharField(max_length=15)
puk = models.CharField(max_length=15)
class phoneForm(ModelForm):
class Meta:
model = Phone
fields = ['phone_num', 'num_calls', 'time_btwn_calls', 'psap']
widgets = {'phone_num': Select(attrs={'class': 'form-control'}),
'num_calls': TextInput(attrs={'class': 'form-control'}),
'time_btwn_calls': TextInput(attrs={'class': 'form-control'}),
'psap': TextInput(attrs={'class': 'form-control'})
}
labels = {
'phone_num': ('Select phone number'),
'num_calls': ('Number of calls'),
'time_btwn_calls': ('Time between calls'),
'psap': ('PSAP'),
}
def __init__(self, *args, **kwargs):
super(phoneForm, self).__init__(*args, **kwargs)
self.queryset = Phone.objects.filter(user_id = request.user.id).values('phone_num')
How can I acces the database properly to filter the phone_num values that belongs to the current user and then set them in phone_num choices?
My template is:
<div class="row">
<div class="col-md-6 col-sm-offset-3">
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %} <!-- obligatorio para protegerse de ataques maliciosos -->
{{ form.as_p }} <!-- pasamos la variable form y con as_p conseguimos <p> -->
<button type="submit" class="btn btn-primary">Send to TCU</button>
</form>
</div>
And my view.py:
def phone_config(request):
phone = Phone.objects.get(phone_num=611111111)
if request.method == 'POST':
form = phoneForm(request, request.POST, instance=phone)
if form.is_valid():
form.save()
return redirect(reverse('gracias'))
else:
form = phoneForm(request, instance=tcu)
return render(request, 'heroconfigurer/heroconfigurer.html', {'form': form})
def gracias_view(request):
return render(request, 'heroconfigurer/gracias.html')
To modify the phone_num field in your form, you access self.fields['phone_num'] in your form's __init__ method.
class phoneForm(ModelForm):
class Meta:
model = Phone
...
def __init__(self, user, *args, **kwargs):
super(phoneForm, self).__init__(*args, **kwargs)
phone_nums = Phone.objects.filter(user=user).values_list('phone_num', flat=True)
self.fields['phone_num'].queryset = Sim.objects.filter(phone_num__in=phone_nums)
When you initialise the form in your view, you need to pass the user, e.g.
form = phoneForm(user, request.POST)
If that doesn't work, please explain why and show your Sim model.
Note a couple of other changes:
No need to use values()
If Sim.user is a foreign key, then you can simplify the filter to filter(user=request.user)
The user has been added to the form's __init__ method.

Categories

Resources