I am new to Django and have a MultiSelectField in my Meal Model. I am also utilizing a MultipleChoiceField with widget CheckBoxSelectMultiple in my Meal Form. When I select a checkbox in the Template and POST the form, I get an error which states, "[ValidationError(["Value ['CHICKEN CASSEROLE'] is not a valid choice."])]}). I am wondering what I am doing wrong here and need some assistance in figuring this out. Any help is appreciated. Below is my code for my Model and Form:
class Meal(models.Model):
day = models.CharField(max_length=255, blank=True)
category = models.CharField(max_length=100, blank=True)
meal_time = models.TimeField(null=True, blank=True, verbose_name='Meal Time')
recipes = MultiSelectField(max_length=5000, choices=[], null=True)
meal_id = models.IntegerField(null=True, blank=True)
menu = models.ForeignKey(Menu, on_delete=models.CASCADE, null=True, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return "%s %s %s %s" % (
self.day, self.category, self.meal_time, self.recipes)
class Meta:
app_label = "mealmenumaster"
managed = True
class MealForm(forms.ModelForm):
day = DynamicChoiceField(choices=[], required=False)
category = forms.ChoiceField(choices=(('', 'None'),) + CATEGORY, required=False)
recipes = forms.MultipleChoiceField(label="Select Recipe(s)",
widget=forms.CheckboxSelectMultiple(), required=False)
meal_id = forms.CharField(widget=forms.HiddenInput(), required=False)
class Meta:
widgets = {'meal_time': TimeInput()}
model = Meal
fields = ['day', 'category', 'meal_time', 'recipes', 'meal_id']
app_label = "mealmenumaster"
def __init__(self, *args, **kwargs):
user_id = kwargs.pop('user_id', None)
super(MealForm, self).__init__(*args, **kwargs)
self.fields['recipes'].choices = [(x.name, x.name) for x in Recipe.objects.filter(user_id=user_id).order_by(Lower('name'))]
self.fields['meal_id'].initial = "0"
self.helper_meal = FormHelper()
self.helper_meal.form_tag = False
self.helper_meal.layout = Layout(
Row(
Div(
Field('day', css_class='form-control'),
css_class='form-group col-md-3 mb0'),
Div(
Field('category', css_class='form-control'),
css_class='form-group col-md-4 mb0'),
Div(
Field('meal_time', css_class='form-control'),
css_class='form-group col-md-4 mb0'),
css_class='form-group col-md-12 mb0'
),
Row(
Div(
Field('recipes', css_class="scrollbar-y"),
Field('meal_id', id='meal_id'),
css_class='form-group col-md-8 mb0'),
css_class='form-group row-md-10 mb0'),
)
And part of my View:
current_user = request.user
user_id = current_user.id
meal_form = MealForm(request.POST, user_id=request.user.id)
if meal_form.is_valid():
menu_id = request.POST.get('menu_id')
if menu_id == "":
messages.error(request, "Create and Save Menu Before Adding Meal(s)")
return redirect('menu')
else:
meal_id = meal_form.cleaned_data['meal_id']
category = meal_form.cleaned_data['category']
meal_time = meal_form.cleaned_data['meal_time']
recipes = meal_form.cleaned_data['recipes']
# get recipes for recipe id
if len(recipes) == 1:
recipes_list = recipes[0]
else:
recipes_list = ', '.join(recipes)
try:
existing_meal = Meal.objects.get(id=int(meal_id))
meal_form = MealForm(request.POST, instance=existing_meal)
# update meal object
saved_meal = meal_form.save(commit=False)
saved_meal.category = category
saved_meal.meal_time = meal_time
saved_meal.recipes = recipes_list
saved_meal.save()
messages.success(request, "Meal Updated")
return HttpResponseRedirect(reverse('menu', args=(),
kwargs={'menu_id': menu_id}))
except Meal.DoesNotExist:
# create new meal object
new_meal = meal_form.save(commit=False)
# set user foreign key
new_meal.user_id = user_id
new_meal.menu_id = int(menu_id)
# save meal
new_meal.save()
new_meal.meal_id = new_meal.id
new_meal.recipes = recipes_list
new_meal.save()
messages.success(request, "Meal Added")
return HttpResponseRedirect(reverse('menu', args=(),
kwargs={'menu_id': menu_id}))
else:
error = meal_form.errors.as_data()
message = "Form Error:", error
messages.error(request, message)
return render_forms(request)
I was able to resolve this issue by adding the actual choices to the model field. As shown below:
RECIPES = [(x.pk, x.name) for x in Recipe.objects.filter().order_by(Lower('name'))] added as choices in the models for the multi-select field "recipes"
Related
I would like your help with a problem that I can't solve or find a solution on the internet.
I have a user registration form that was working correctly before. But feel the need to insert a dynamic formset.
However, now with the formset when filling out and sending the form, no data is saved in the database and instead of being redirected to a list of users, I am redirected to the form again already filled with the data that failed to be sent and without showing any kind of error.
models.py
class Contato(models.Model):
tipo = (
('Residencial', 'Residencial'),
('Comercial', 'Comercial'),
('Celular', 'Celular'),
('WhatsApp', 'WhatsApp'),
)
# Contato
email_p = models.EmailField(blank=True, null=True, verbose_name='E-mail pessoal')
email_c = models.EmailField(blank=True, null=True, verbose_name='E-mail corporativo')
proprietario = models.ForeignKey(Perfil, on_delete=models.CASCADE)
tipo_contato = models.CharField(verbose_name='Tipo', choices=tipo, max_length=11, blank=True, null=True)
telefone = models.CharField(max_length=16, blank=True, null=True)
def __str__(self):
return self.proprietario, self.telefone
forms.py
import datetime
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.contrib.auth.models import Group
from Cadastro.models import Local
from django.forms import NumberInput, inlineformset_factory
from Usuarios.models import Contato, Perfil
class UsuarioForm(UserCreationForm):
tipo = (
('Residencial', 'Residencial'),
('Comercial', 'Comercial'),
('Celular', 'Celular'),
('WhatsApp', 'WhatsApp'),
)
contratacao = [(
('CLT', 'CLT'),
('Estagiário', 'Estagiário'),
('Prestador de Serviço (MEI)', 'Prestador de Serviço (MEI)'),
)]
# Dados pessoais
nome_completo = forms.CharField(max_length=150)
nome_mae = forms.CharField(max_length=150, label='Nome do Mãe', required=False)
nome_pai = forms.CharField(max_length=150, label='Nome do Pai', required=False)
cpf = forms.CharField(max_length=15, label='CPF')
rg = forms.CharField(max_length=15, label='RG')
org_exped = forms.CharField(max_length=15, label='Org. Exp')
data_nasc = forms.DateField(label="Dt. de Nascimento", required=True, widget=NumberInput(attrs={'type': 'date'}))
data_emiss = forms.DateField(label="Data de Emissão", required=True, widget=NumberInput(attrs={'type': 'date'}))
# Endereço
logradouro = forms.CharField(max_length=50)
numero_casa = forms.IntegerField(max_value=9999, min_value=0, label='Número', required=False)
complemento_casa = forms.CharField(max_length=10, label='Complemento', required=False)
estado = forms.CharField(max_length=30)
bairro = forms.CharField(max_length=30)
cidade = forms.CharField(max_length=30)
cep = forms.CharField(max_length=15)
# Contato
telefone = forms.CharField(max_length=16)
email_p = forms.EmailField(max_length=100, label='E-mail pessoal')
email_c = forms.EmailField(max_length=100, label='E-mail corporativo')
tipo_contato = forms.ChoiceField(choices=tipo)
dt_cadastro = forms.DateField(label='Dt. de Cadastro', disabled=True, required=False,
widget=NumberInput(attrs={'type': 'date', 'value': datetime.date.today()}))
dt_inicio = forms.DateField(label='Dt. de Inicio', required=False, widget=NumberInput(attrs={'type': 'date'}))
# ForeignKeys
local = forms.ModelChoiceField(queryset=Local.objects.all())
grupo = forms.ModelChoiceField(queryset=Group.objects.all())
class Meta:
model = User
fields = ['username',
'nome_completo',
'rg',
'data_emiss',
'org_exped',
'cpf',
'email',
'data_nasc',
'password1',
'password2',
'grupo',
]
class ContatoForm(forms.ModelForm):
class Meta:
model = Contato
fields = '__all__'
UsuarioFormSet = inlineformset_factory(Perfil, Contato, form=ContatoForm, fields=('tipo_contato', 'telefone'), extra=1)
views.py
""" Implementando classes para o método de CREATE """
class UsuarioCreate(GroupRequiredMixin, LoginRequiredMixin, SuccessMessageMixin, CreateView):
template_name = 'Cadastro/formulario_usuario.html'
group_required = u"Adminstrador"
form_class = UsuarioForm
success_url = reverse_lazy('listar-usuario')
success_message = "Cadastrado com sucesso"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['titulo'] = 'Registro de novo usuário'
context['botao'] = 'Cadastrar'
if self.request.POST:
context['form'] = UsuarioForm(self.request.POST)
context['contato_form'] = UsuarioFormSet(self.request.POST)
else:
context['form'] = UsuarioForm()
context['contato_form'] = UsuarioFormSet()
return context
def form_valid(self, form):
group = self.request.POST.get('grupo')
grupo = get_object_or_404(Group, id=group)
self.object.groups.add(grupo)
self.object.save()
Perfil.objects.create(
usuario=self.object,
nome_completo=self.request.POST.get('nome_completo'),
cpf=self.request.POST.get('cpf'),
rg=self.request.POST.get('rg'),
org_exp=self.request.POST.get('org_exped'),
telefone=self.request.POST.get('telefone'),
local=self.request.POST.get('local'),
data_nascimento=self.request.POST.get('data_nasc'),
data_emissao=self.request.POST.get('data_emiss'),
nome_mae=self.request.POST.get('nome_mae'),
nome_pai=self.request.POST.get('nome_pai'),
tipo_contato=self.request.POST.get('tipo_contato'),
numero_casa=self.request.POST.get('numero_casa'),
Estado=self.request.POST.get('estado'),
Cidade=self.request.POST.get('cidade'),
Bairro=self.request.POST.get('bairro'),
complemento=self.request.POST.get('complemento_casa'),
dt_cadastro=self.request.POST.get('dt_cadastro'),
dt_inicio=self.request.POST.get('dt_inicio'),
email_p=self.request.POST.get('email_p'),
email_c=self.request.POST.get('email_c'),
)
context = self.get_context_data()
forms = context['form']
formset = context['contato_form']
if forms.is_valid() and formset.is_valid():
self.object = form.save()
forms.instance = self.object
formset.instance = self.object
forms.save()
formset.save()
else:
return self.render_to_response(self.get_context_data(form=form))
return super(UsuarioCreate, self).form_valid(form)
I have the following three models:
class User(AbstractUser):
username = None
name = models.CharField(max_length=255)
email = models.EmailField(unique=True)
account_type = models.CharField(
choices=AccountType.choices,
default=AccountType.GENERAL,
max_length=8,
)
first_name = None
last_name = None
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["name"]
objects = UserManager()
#property
def total_likes(self):
queryset = (
self.works.filter(visibility=Visibility.PUBLIC)
.select_related()
.annotate(likes=models.Count("social"))
)
return (
queryset.aggregate(models.Sum("likes")).get("likes__sum")
or 0
)
def __str__(self) -> str:
return self.name
class WorkImage(models.Model):
user = models.ForeignKey(
to=User, on_delete=models.CASCADE, related_name="works"
)
title = models.CharField(max_length=255)
image = models.ImageField(upload_to=work_image_directory_path)
#property
def likes(self):
return self.social.count()
def __str__(self) -> str:
return f"{self.user.name}'s {self.work_image_type} {self.title}"
class WorkImageSocial(models.Model):
work = models.ForeignKey(
to=WorkImage, on_delete=models.CASCADE, related_name="social"
)
liked_by = models.ForeignKey(
to=User, on_delete=models.CASCADE, related_name="liked_works"
)
def __str__(self) -> str:
return f"{self.liked_by.name}=>{self.work.title}"
I am writing a custom ordering filter to get the "most liked" users, what I want to do is annotate users with a field called "likes" which will have the sum of all likes on their work images, how do I achieve this?
I use Django + MongoDB /Djongo for backend on Windows10/VSCode. How is it to instantiate document’s “ObjectId” like it is for other fields using Python? I have been struggling for a several days. Please help. Code example, below:
from djongo import models
class Blog(models.Model):
id= models.AutoField(
auto_created = True,
unique=True,
primary_key = True,
serialize = False,
verbose_name ='ID_nama: ')
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name, self.id
# return self.tagline
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField(default=date.today)
authors = models.ManyToManyField(Author)
number_of_comments = models.IntegerField(default=0)
number_of_pingbacks = models.IntegerField(default=0)
rating = models.IntegerField(default=5)
def __str__(self):
return self.headline
Here is the document JSON from MongodDB:
{
“_id”: {
“$oid”: “626b6627f0d91c65e9f78cc6”
},
“id”: 5,
“name”: “Beatles Blog”,
“tagline”: “Beatles tour of the Americas.”
}
My target is to be able to capture the “ObjectId” => “_id”: {
“$oid”: “626b6627f0d91c65e9f78cc6”, and save it to another new field for other use/purpose.
I have a Django web application in which I would like to integrate a local payment API in order to enable customers who want to use their money from this payment application to pay their car insurance but honestly, I don't have any idea of how to do it.
Below are the related models (Contrat and Reglement):
class Contrat(models.Model):
Statut_contrat = (
('Encours', 'Encours'),
('Suspendu', 'Suspendu'),
('Expiré', 'Expiré'),
)
categorie_choices =(
('Tourisme', 'Tourisme'),
('Transport', 'Transport')
)
# numero_de_contrat = shortuuid.uuid()
type_contrat = models.ForeignKey(TypeContrat, on_delete=models.CASCADE, null=True, blank=False)
tca = models.DecimalField(_('TCA 4%'),max_digits=10, decimal_places=2, default=0.00)
numero_de_contrat = models.CharField(max_length=50, blank=True, null=True,db_index=True, unique=True)
statut_assurance =models.CharField(max_length=15, choices=Statut_contrat, default='Non')
vehicule = models.ForeignKey(Vehicule, on_delete=models.CASCADE)
utilisateur = models.ForeignKey(User, on_delete=models.CASCADE)
nombre_de_mois = models.IntegerField(null=True, blank=True)
sous_couvert = models.CharField(_('S/C'),max_length=200, null=True, blank=True)
categorie = models.CharField(max_length=50, choices=categorie_choices, null=False, blank=False, default='Tourisme')
created = models.DateField(auto_now_add=True)
modified = models.DateField(auto_now=True)
active = models.BooleanField(default=True)
remainingdays=models.IntegerField(default=0)
blocked_date=models.DateField()
unblocked_date = models.DateField(null=True, blank=True)
history = HistoricalRecords()
class Meta:
ordering=('-created',)
#property
def static_id(self):
'C{0:07d}'.format(self.pk)
def __str__(self):
return str(self.numero_de_contrat)
def save(self, *args, **kwargs):
self.tca=self.type_contrat.montant_du_contrat*Decimal(0.04)
if self.statut_assurance=="Suspendu":
dt=abs(self.blocked_date-self.modified)
print('Difference est:',dt)
numberOfDaysLeft= self.remainingdays-dt.days
print('Big diff',numberOfDaysLeft)
self.remainingdays=numberOfDaysLeft
self.blocked_date=date.today()
super(Contrat, self).save(*args, **kwargs)
def activeStatus(self):
if self.nombre_de_mois==0:
return self.active==False
else:
return self.active==True
def get_NbDays(self):
if self.statut_assurance=='Encours':
# nb_Days = timedelta(days=self.remainingdays)+date.today()
nb_Days = timedelta(days=self.remainingdays)+self.blocked_date
print('Date de fin', nb_Days)
return nb_Days
elif self.statut_assurance=='Suspendu':
nb_Days = timedelta(days=self.remainingdays) + self.blocked_date
return nb_Days
else:
nb_Days = self.modified
return nb_Days
class Reglement(models.Model):
payment_list = (('Espece', 'Espece'),
('Cheque', 'Cheque'),
('Carte de crédit', 'Carte de crédit'),
('Carte de débit', 'Carte de débit'),
('A crédit', 'A crédit'),)
code_reglement = models.CharField(max_length=50, blank=True, null=True, db_index=True, unique=True)
contrat = models.ForeignKey(Contrat, on_delete=models.CASCADE)
utilisateur = models.ForeignKey(User, on_delete=models.CASCADE)
date_reglement = models.DateField(auto_now_add=True)
montant_a_regler = models.DecimalField(max_digits=10, decimal_places=2)
mode_de_paiment = models.CharField(max_length=15,choices=payment_list)
created = models.DateField(auto_now_add=True)
modified = models.DateField(auto_now=True)
regle = models.BooleanField(default=False)
history = HistoricalRecords()
class Meta:
ordering=('-created',)
#property
def static_id(self):
'R{0:07d}'.format(self.pk)
Please assist me
Good day, I want to strftime the created model instance and display it in the HTML template(as a transaction_id). But I don't seem to get it right. Thanks for your help.
models.py
class Order(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
address = models.CharField(max_length=250)
phone_number = models.CharField(max_length=20)
city = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
braintree_id = models.CharField(max_length=150, blank=True)
coupon = models.ForeignKey(Coupon, related_name='orders', null=True, blank=True, on_delete=models.SET_NULL)
discount = models.IntegerField(default=0, validators=[
MinValueValidator(0),
MaxValueValidator(100)
])
views.py
def order_list(request):#datetime.now().strftime("%Y%m%d%H%M%S")
transaction_id = Order.objects.get(created)
orders = Order.objects.all()
current_user = request.user
success = Order.objects.filter(user=current_user.id).filter(paid=True)
fail = Order.objects.filter(user=current_user.id).filter(paid=False)
return render(request, 'orders/order/order_list.html', {
'success': success,
'fail': fail,
'current_user': current_user,
'orders':orders,
'transaction_id':transaction_id,
})
html
<p class="card-text">
<mark style="color: whitesmoke; background-color: brown;border-radius: 3px;font-weight: bold;">{{transaction_id}}</mark>
</p>
you getting error of "transaction_id = Order.objects.get(created)" line
what is "created" in get() method
Well, this is what I did to fix this
I added the strftime func in my models.py
models.py
def htmldisplaytime(self):
time = self.created.strftime("%Y%m%d%H%M%S")
return time