How I can show selectbox from models in my form? - django

How I can show selectbox from models in my form. Output for below code does not show options for selectbox.
#models.py
class Reg(models.Model):
options = (
('one', 'option1'),
('two', 'option2'),
)
types = models.CharField(max_length=30, choices=options,null=True)
company = models.CharField(max_length=50,null=True)
#form.py
from django import forms
from .models import Reg
class Regform(forms.ModelForm):
class Meta:
model = Reg
fields = ['types','company']
types = forms.CharField(
widget=forms.Select(
attrs={'class': 'form-control'}
),
label="Type",
)
templatefie.html
{% load static %}
{% block main %}
<form method="post" class="post-form" autocomplete="off">
{% csrf_token %}
<div class="row col-md-4 m-auto">
<div>
{{people.as_p}}
<button type="submit" class="save btn btn-primary mt-5">apply</button>
</div>
</div>
</form>
{% endblock %}

Labels and widgets can be defined separately.
Class RegForm(forms.ModelForm):
class Meta:
model = Reg
fields = ['types','company']
labels = {
'types': 'Types',
'company': 'Company'
}
widgets = {
'types': Select(attrs={'class':'form-control'})
}
Create a view function that creates instance of the "Reg" modelform and pass in context to the template context = {'form_obj':Regform()}
{% load static %}
{% block main %}
<form method="post" class="post-form" autocomplete="off">
{% csrf_token %}
<div class="row col-md-4 m-auto">
<div>
{{form_obj.types.label_tag}}
{{form_obj.types}}
<button type="submit" class="save btn btn-primary">apply</button>
</div>
</div>
</form>
{% endblock %}

Related

Edit item within views in Django

There is some problem, I'm trying to update the product on the client by making changes and clicking on the update button - my page is refreshing w/o updating info, so the product has the same data as before. But in the logs, the status code of the GET request is 200 and shows the updated object in the database. When I try to update through the admin Django dashboard, everything works successfully, the problem is only on the client side of the web application. What issues can there be?
Thank you in advance!
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
CATEGORY = (
('Stationary', 'Stationary'),
('Electronics', 'Electronics'),
('Food', 'Food'),
)
class Product(models.Model):
name = models.CharField(max_length=100, null=True)
quantity = models.PositiveIntegerField(null=True)
category = models.CharField(max_length=50, choices=CATEGORY, null=True)
def __str__(self):
return f'{self.name}'
class Order(models.Model):
name = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
customer = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
order_quantity = models.PositiveIntegerField(null=True)
def __str__(self):
return f'{self.customer}-{self.name}'
views.py
#login_required(login_url='user-login')
#allowed_users(allowed_roles=['Admin'])
def product_edit(request, pk):
item = Product.objects.get(id=pk)
if request.method == 'POST':
form = ProductForm(request.POST, instance=item)
if form.is_valid():
form.save()
return redirect('dashboard-products')
else:
form = ProductForm(instance=item)
context = {
'form': form,
}
return render(request, 'dashboard/products_edit.html', context)
forms.py
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = '__all__'
html template:
{% extends 'partials/base.html' %}
{% block title %}Products Edit Page{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row my-4">
<div class="col-md-6 offset-md-3 p-3 bg-white">
<h3>Edit Item</h3>
<hr>
<form>
{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-info" type="submit" value="Confirm">
</form>
</div>
</div>
{% endblock %}
You have forgotten to pass POST method you are using GET.
{% extends 'partials/base.html' %}
{% block title %}Products Edit Page{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row my-4">
<div class="col-md-6 offset-md-3 p-3 bg-white">
<h3>Edit Item</h3>
<hr>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-info" type="submit" value="Confirm">
</form>
</div>
</div>
{% endblock %}

Django - UpdateView changes are not saved, success_url is not used

I think I have a pretty basic UpdateView but the object is not saved when I submit the form. The success_url is never called. When I click the Update button, the form refreshes and I stay on the same page. I am able to update the object via admin, so I believe the model is working fine. I am not getting any errors.
urls
path('classroomdetail/<uuid:classroom_id>/',
views.classroomdetail, name='classroomdetail'),
path('classedit/<uuid:pk>/', views.ClassroomUpdateView.as_view(), name='classupdate'),
Model
class Classroom(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
classroom_name = models.CharField(max_length=20)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
students = models.ManyToManyField(Student)
class Meta:
constraints = [models.UniqueConstraint(
fields=['user', 'classroom_name'], name="unique-user-classroom")]
def __str__(self):
return self.classroom_name
views
class ClassroomUpdateView(UpdateView):
model = Classroom
fields = ['classroom_name']
template_name_suffix = '_update'
success_url = reverse_lazy('gradebook:classroom')
template
{% extends 'base.html' %} {% load static %} {% block content %}
{% load crispy_forms_tags %}
<div class="container">
<div class="row">
<div class="col">
<h3>This Classroom belongs to {{ classroom.course }}</h3>
</div>
</div>
<div class="row">
<div class="col-md-3">
<form class="form-group">
{% csrf_token %}{{ form|crispy }}
<input type="submit" class="btn btn-primary mt-2 mb-2" value="Update">
</form>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="ps-2">Cancel
</div>
</div>
</div>
{% endblock content %}
I was missing method="post" in my template. Correct line:
<form method="post" class="form-group">

ModelForm is not generating any form

So my problem is that even though I have created the forms from my model and provided my views with those forms, the related template is not displaying any form:
The following is my forms.py :
from django import forms
from django.contrib.auth.models import User
from .models import Account
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField(max_length=100)
class Meta:
model = User
fields = ['username', 'email']
class AccountUpdateForm(forms.ModelForm):
class Meta:
model= Account
fields = ['image']
And the next one is my views.py:
from .forms importUserUpdateForm, AccountUpdateForm
def account(request):
user_update_form = UserUpdateForm()
profile_update_form = AccountUpdateForm()
return render(request, 'blog/profile.html', {
'user_update_form':user_upate_form,
'profile_update_form':profile_update_form
})
But the following template does not show any form
{% extends './base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-12 d-flex flex-column justify-content-center align-items-start">
<img src="{{ user.account.image.url }}" alt="" class="user-profile-pic">
<label for="user-profile-pic-input">Choose an image</label>
<input type="file" class="form-control-files w-100" id="user-profile-pic-input" name='user-profile-pic-input'>
</div>
</div>
<div class="row">
<div class="col-12">
<form method="POST">
{% csrf_token %}
{{ user_update_form }}
{{ profile_update_form }}
<input type="submit" value="Save changes!" class="btn btn-info btn-block">
</form>
</div>
</div>
{% endblock %}
I had this problem just yesterday. It worked when i called the form class without brackets ()
Try this:
user_update_form = UserUpdateForm
profile_update_form = AccountUpdateForm
If this doesn't work you should probably go down the formset path (inlineformset_factory). It's used to connect modelforms linked by a foreign key. It works with one-to-one and one-to-many relationships.

How to correctly localize fields in forms?

I use Django 3.0.4 and Crispy Forms 1.9.0
I have the following model:
class App(models.Model):
name = models.CharField(max_length=256, db_index=True, verbose_name=_('Name'))
platform = models.ForeignKey(Platform, on_delete=models.CASCADE, verbose_name=_('Platform'))
package_name = models.CharField(max_length=512, unique=True, verbose_name=_('Package name'))
created_at = models.DateTimeField(auto_now_add=True, db_index=True, verbose_name=_('Created Date'))
Form:
class CreateAppForm(forms.ModelForm):
class Meta:
model = App
fields = ('name', 'platform', 'package_name',)
localized_fields = '__all__' # I've tried to enumerate fields as tuple
# labels = { # I've tried to uncomment it
# 'name': _('Name'),
# 'platform': _('Platform'),
# 'package_name': _('Package name'),
# }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['platform'].queryset = Platform.objects.filter(is_enabled=True)
And template:
{% extends 'base.html' %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block title %}{% trans "Create application" %}{% endblock %}
{% block page_title %}{% trans "Create application" %}{% endblock %}
{% block content %}
<div class="row">
<div class="col">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">{% trans "Create application" %}</h6>
</div>
<div class="card-body">
<form class="form" action="{% url 'apps:create' %}" method="post">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-success btn-lg" type="submit"><i class="fa fa-check"></i> {% trans "Create" %}</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
All strings in .po files are localized and compiled (and work everywhere but in forms).
The form renders correctly, but the fields' labels are not localized:
What's wrong?
Django documentation recommends to use gettext_lazy for the verbose names of model fields.
This is essential when calls to these functions are located in code paths that are executed at module load time.
This is something that can easily happen when defining models, forms and model forms, because Django implements these such that their fields are actually class-level attributes. For that reason, make sure to use lazy translations in the following cases:
Model fields and relationships verbose_name and help_text option values

Can't get form errors when using crispy forms

I'm using django-crispy-forms, a third party library, in a Django project, I would like to customize a form to get the errors at top of the form, but I can't.
This is a snippet of the code:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="col-sm-6">
<h1>Add New Task</h1>
<form action="" method="post">{% csrf_token %}
<div class="row">
<div class="col-sm-12">{{ form|as_crispy_errors:"bootstrap3" }}</div>
<div class="col-sm-10">{{ form.project|as_crispy_field }}</div>
<div class="col-sm-2" id="add-new">
Add new
</div>
</div>
<div class="row">
<div class="col-sm-12">{{ form.title|as_crispy_field }}</div>
</div>
<button class="btn btn-primary" type="submit">Add</button>
</form>
</div>
{% endblock content %}
The view:
def new_task(request):
form = NewTaskForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
return redirect('/pomodoro/home')
return render(request, 'pomodoro/new-task.html', {
'form': form,
})
This is my form:
from django import forms
from .models import Task
class NewTaskForm(forms.ModelForm):
class Meta:
model = Task
fields = ['project', 'title',]