I need your help in order to know How I can actualize my Django template from get_context_data.
I have this class in my view :
class IdentitySocieteResumeView(LoginRequiredMixin,TemplateView) :
template_name = 'Identity_Societe_Resume.html'
model = Societe
def get_context_data(self, **kwargs) :
context_data = super(IdentitySocieteResumeView, self).get_context_data(**kwargs)
id = self.kwargs['id']
societe = get_object_or_404(Societe, pk=id)
obj = Societe.objects.filter(Nom=societe.Nom, SIRET=societe.SIRET, SIREN=societe.SIREN, Ville=societe.Ville)
if obj:
sc_obj = obj[0]
NIU = lib.Individu_Recherche.NIUGeneratorSociete(ModelBase=societe)
societe.NumeroIdentification = NIU
societe.save()
context_data['queryset'] = obj
return context_data
And this important function in lib.Individu_Recherche :
def NIUGeneratorSociete(ModelBase) :
create_year_temp = str(ModelBase.Creation.year)
create_year_temp2 = str(create_year_temp.split(" "))
create_year = create_year_temp2[4] + create_year_temp2[5]
''' A process which let to generate NumeroIdentification '''
NumeroIdentification = force_text('%s-%s%s-%s-%s-%s' % ('E', create_year, create_month, create_city, key, create_country_id))
return NumeroIdentification
Part of my template :
{% block content %}
<div class="title_subtitle_space"></div>
<div class="resume">
{% for societe in queryset %}
Votre société porte le numéro : <b> {{ societe.id}} </b> <p></p>
N° identification attribué : <b>{{societe.NumeroIdentification}}</b> <br></br>
{% endfor %}
{% endblock %}
I'm sure my template is loaded before to execute this function and I get in my template NumeroIdentification = None but in my database this field is well-filled.
My question is : How I can display my variable NumeroIdentification with the good value in my template (value stored in my database) instead of None ?
If I press Cmd + R (MacOS Actualize), NumeroIdentification won't be None but a different value. I would like to get this value in my template the first time.
It's pretty easy with FBV, but with CBV I don't overcome to make it
EDIT :
I add my function NIUGeneratorSociete :
def NIUGeneratorSociete(ModelBase) :
create_year_temp = str(ModelBase.Creation.year)
create_year_temp2 = str(create_year_temp.split(" "))
create_year = create_year_temp2[4] + create_year_temp2[5]
create_month_temp = ModelBase.Creation.month
if len(str(create_month_temp)) == 1 :
create_month = '0' + str(create_month_temp)
else :
create_month = create_month_temp
create_city = Villes[ModelBase.Ville]
key_temp = randint(0,999999)
if len(str(key_temp)) == 1 :
key = '00000' + str(key_temp)
elif len(str(key_temp)) == 2 :
key = '0000' + str(key_temp)
elif len(str(key_temp)) == 3 :
key = '000' + str(key_temp)
elif len(str(key_temp)) == 4 :
key = '00' + str(key_temp)
elif len(str(key_temp)) == 5 :
key = '0' + str(key_temp)
else :
key = key_temp
create_country = ModelBase.Pays
create_country_id = None
if create_country == "CG" :
create_country_id = 1
else :
create_country_id = 2
NumeroIdentification = force_text('%s-%s%s-%s-%s-%s' % ('E', create_year, create_month, create_city, key, create_country_id))
return NumeroIdentification
Unfortunately, this code is all kinds of confused. You're getting the same object in multiple different ways, and updating one copy but expecting the others to reflect the change.
You first get the relevant object as societe. Then for some reason you do another query on that model with all the fields of that object, to get a queryset consisting of one object. Then you do some manipulation of the original object and save it, but don't pass it to the context; instead you pass the queryset.
Your code can be simplified to just this:
def get_context_data(self, **kwargs) :
context_data = super(IdentitySocieteResumeView, self).get_context_data(**kwargs)
id = self.kwargs['id']
societe = get_object_or_404(Societe, pk=id)
NIU = lib.Individu_Recherche.NIUGeneratorSociete(societe)
societe.NumeroIdentification = NIU
societe.save()
context_data['societe'] = societe
return context_data
and the template:
{% block content %}
<div class="title_subtitle_space"></div>
<div class="resume">
Votre société porte le numéro : <b> {{ societe.id}} </b> <p></p>
N° identification attribué : <b>{{societe.NumeroIdentification}}</b> <br></br>
</div>
</div>
{% endblock %}
There are also some strange things going on in your library function. one is that you pass the object as the parameter ModelBase; although it doesn't matter what you call it, ModelBase is a class, but your parameter is an instance of your Societe class. You should call things what they are.
I can't correct that function though as it is clearly incomplete; all of create_month, create_city, key, create_country_id are undefined.
Finally, you should consider if any of this is appropriate. The update function is called from get_context_data in a normal GET request of your page; it would be very surprising for an object to be updated like this on a GET. Really this should be done on a POST only.
Lots of weird things going on here.
After societe = get_object_or_404(Societe, pk=id) you will have a Societe instance (or 404). You then filter Societe to get a list of objects that have the same properties at the instance you already received, and then fetch the first one of those. Why not just obj = get_object_or_404(Societe, pk=id) and skip the rest?
You then mix obj, societe and sc_obj. Your actions on one of them will be lost on the others until you fetch them again, which is probably why this works on refresh. Might be helpful to see your Societe model to confirm though.
Related
I am trying to assign these to users and using a form for the same model to update it but it doesn't work for some reason, this is the code
def assign_blanks(request):
if request.method == 'POST':
form = assign_blank_form(data=request.POST)
from_value = request.POST.get("from_value", "")
to_value = request.POST.get("to_value", "")
blanks = blank.objects.all()
for b in blanks:
if b.number >= int(from_value) and b.number >= int(to_value):
b.advisor = form.instance.advisor
print(b.number)
return render(request, 'assign_blanks.html')
else:
form = assign_blank_form
return render(request, 'assign_blanks.html', {'form':form})
class assign_blank_form(ModelForm):
class Meta:
model = blank
fields = ['advisor']
<form class="box" method = "post">
{% csrf_token %}
<h1>Air Ticket Sales</h1>
{{ form }}
assign from:
<input type="number" name="from_value" value="{{ from_value }}">
assign to:
<input type="number" name="to_value" value="{{ to_value }}">
<input type="submit" name="" value="Assign blanks">
</form>
You are not calling save() method after assigning a advisor. Change your view to:
def assign_blanks(request):
if request.method == 'POST':
form = assign_blank_form(data=request.POST)
from_value = request.POST.get("from_value", "")
to_value = request.POST.get("to_value", "")
blanks = blank.objects.all()
for b in blanks:
if b.number >= int(from_value) and b.number >= int(to_value):
b.advisor = form.instance.advisor
b.save() # call save method.
print(b.number)
return render(request, 'assign_blanks.html')
else:
form = assign_blank_form() # instantiate a form for GET request.
return render(request, 'assign_blanks.html', {'form':form})
Also you need to instantiate a form for GET request. You are missing () after your form name assign_blank_form.
You can further optimize the performance by avoiding calling save() multiple times. Create a list of b.id in your if condition and then use update() method. It will update multiple records in a single query. Adding that snippet of code here.
blanks = blank.objects.all()
b_ids = []
for b in blanks:
if b.number >= int(from_value) and b.number >= int(to_value):
b_ids.append(b.id)
blank.objects.filter(id__in=b_ids).update(advisor=form.instance.advisor)
return render(request, 'assign_blanks.html')
hello I am new in django and I have some questions (I do not speek english so good ,sorry)
I want to recive data from the template (input element)
and calculate this with model data field.
for exemple I have money_for_month = 1000$ in model field.
and the input from the user is "3" (e.g. 3 month) so I want the result to be 3000$ store it in a variable and display it bellow the input element.
if someone can help. thanks.
this is my models
class Mitnadv(models.Model):
f_name = models.CharField(max_length = 30)
money_for_month = models.CharField(max_length = 4)
and this is my view
class MitnadvDetailView(DetailView):
model = Mitnadv
template_name = "mit_app/mitnadv-detail.html"
context_object_name = "mit"
list_var = {}
def post(self,request, **kwargs):
num_m = request.POST["num-month"]
self.list_var["num_month"] = num_m
return HttpResponseRedirect(self.request.path_info)
and this is my template
<h2>pay for x mounth</h2>
<form action="" method="POST">
{% csrf_token %}
<input type="number" name="num-month">
<input type="submit" value="submit">
</form>
Put this method within the class and implement your needs.
def post(self,request, **kwargs):
obj = MyModel.objects.get()
money_for_month = obj.money_for_month
num = request.POST.get('num-month', 0) % 0 is the default value if the num-month doesn't exist
result = int(money_for_month) * int(num)
return render(request, 'mit_app/mitnadv-detail.html', {'data': result})
I am trying to make changes in two models at the same time. So, according to one topic on the forum, I created two forms in one view and added it to one html.
I think I am doing something wrong in my second form. Why my value in my model does not change to False?
It looks more or less like that.
views.pl
if request.method == 'POST' and 'btn_massage_order' in request.POST:
ordering_form = OrderingMassageForm(data=request.POST)
if ordering_form.is_valid():
ordering = ordering_form.save(commit=False)
massage_product = query_product # nazwa produkty
masseurs = query_user # massage
massage_time_interval = time # time example 60 min
price_massage = price # price
day_week = clean_my_date # day week
time_compartment = ordering_form.cleaned_data['time']
[...]
ordering.massage_product = massage_product
ordering.masseurs = masseurs
ordering.massage_time_interval = massage_time_interval
ordering.time_compartment = time_compartment
ordering.price = price_massage
ordering.day_week = day_week
[...]
ordering.save()
else:
ordering_form = OrderingMassageForm()
#next form i views
if request.method == 'POST' and 'btn_massage_order' in request.POST:
ordering_form = OrderingMassageForm(data=request.POST)
ordering_form_on_off = TimeOnTimeOff(data=request.POST)
if ordering_form_on_off.is_valid() and ordering_form.is_valid():
ordering_form_on_off = ordering_form_on_off.save(commit=False)
# the value that will be save
reservation = False
# I receive my object
time_compartment = ordering_form.cleaned_data['time']
# assigning my object
ordering_form_on_off.time_compartment = reservation
#save
ordering_form_on_off.save()
else:
ordering_form_on_off = TimeOnTimeOff()
forms.py
class OrderingMassageForm(forms.ModelForm):
class Meta:
model = OrderingMassage
fields = ('time',
'place',
'payment_method',
'name',
'surname',
[...]
class TimeOnTimeOff(forms.ModelForm):
class Meta:
model = Time
fields = ('free_or_no',
)
widgets = {
'free_or_no': forms.HiddenInput(),
}
models.py
(in which I try to change the value through a second form that does not work)
class Time(models.Model):
day_time = models.ForeignKey(DayTime, on_delete=models.CASCADE)
compartment = models.CharField(max_length=11)
free_or_no = models.BooleanField(default=True)
time_equivalent = models.IntegerField()
template
<form action="." method="post">
{% csrf_token %}
{{ ordering_form.as_p }}
<button type="submit" name="btn_massage_order" class="btn btn-primary">Potwierdż rezerwacje</button>
</form>
Any help will be appreciated.
Someone please tell me where I am going wrong. What I'm trying to do is have the user input the quantity of a product that they want and when submitted, if that quantity is more than 0 then display a form equal to the quantity. There are multiple products so I used an if statement to say where the post has this product name, display this form. The result I'm getting is just the forms for the last product sent over. So in a list of [ eggs, ham ], I only get a form for ham . Please help if possible, this is my code below.
View:
if request.method =='POST':
session = request.session._session_key
formtype = request.POST.getlist('name')
i = 0
while i < len(formtype):
for f in formtype:
if f == 'eggs':
item = CompReg.objects.get(sessionid = session, name='eggs')
extra = item.quantity
listmemformset = modelformset_factory(ProBachata, form=ProBachataF,extra=extra)
formset = listmemformset()
elif f == 'ham':
item = CompReg.objects.get(sessionid = session, name='ham')
extra = item.quantity
listmemformset = modelformset_factory(ProBachata, form=ProBachataF,extra=extra)
formset = listmemformset()
i += 1
else:
extra = 0
Template:
{{formset.as_p}}
Actually i didn't fully understand your code (why used while, why you getting item.quantity from db, quantity musn't be in POST data?), but your code can be something like;
if request.method =='POST':
session = request.session._session_key
formtype = request.POST.getlist('name')
formsets = []
for f in formtype:
if f == 'eggs':
item = CompReg.objects.get(sessionid=session, name='eggs')
elif f == 'ham':
item = CompReg.objects.get(sessionid=session, name='ham')
extra = item.quantity
listmemformset = modelformset_factory(ProBachata, form=ProBachataF, extra=extra)
formset = {'name': f, 'form':listmemformset()}
formsets.append(formset)
else:
extra = 0
Template:
{% for formset in formsets %}
name: {{formset.name}}
{{formset.form.as_p}}
{% endfor %}
I'm generating a form from metadata
class MeasureForm(forms.Form):
def __init__(self,*args,**kwargs):
super(MeasureForm,self).__init__()
measure_id = kwargs['measure_id']
m = Measure.objects.get(pk=measure_id);
if (m):
# add the measure identifier as a hidden field
self.fields["measure_id"] = forms.IntegerField(initial = m.id , widget=forms.HiddenInput())
for mp in MeasureParameters.objects.filter(measure = m):
# get the NVL'ed copy of the parameter
p = mp.get_parameter_for_measure()
if not p.is_modifiable:
# the file has a constant value
if (p.values and p.default): # constant must have both values and default index
value_ = p.values[p.values.keys()[p.default-1]];
self.fields[p.name] = forms.IntegerField(
label = p.description ,
initial = value_,
help_text = p.help_text)
self.fields[p.name].widget.attrs['readonly'] = True
else:
raise Exception("Parameter set as unmodifiable but has no value. \
[measure: %s, parameter: %s, measureparameter %s]"
% (m.id , p.id , mp.__unicode__()))
elif (p.values):
# convert hstore dict to list of tuples for the choices to read
values_ = [(v, k) for k, v in p.values.iteritems()];
# set default if exists , else take the first item
default_ = values_[p.default-1][0] if p.default else values_[0][0]
self.fields[p.name] = forms.ChoiceField(
label = p.description ,
choices = values_ ,
initial = default_,
help_text = p.help_text)
else:
self.fields[p.name] = forms.IntegerField(label = p.description, help_text = p.help_text)
if (not p.is_visible):
self.fields[p.name].widget = forms.HiddenInput()
else:
raise Exception ("Could not find measure. [measure %s]" % (m.id))
def clean(self):
return self.cleaned_data;
this is my view
def index(request,measure_id = None):
owners = Owner.objects.all()
form = None
result = None
title = None;
msg = None;
# handle the form
if request.method == 'POST': # the form has been submitted
form = MeasureForm(request.POST, measure_id = request.POST.get('measure_id')) # A form bound to the POST data
result = -100
if form.is_valid(): # All validation rules pass
result = 100
msg = "%s" % repr(form.errors) # list of validation errors
else:
if (measure_id):
title = Measure.objects.get(pk=measure_id).name;
# make an unbound form
form = MeasureForm(measure_id = measure_id)
return render(request, 'calc/index.html' ,
{'owners' : owners,
'form' : form ,
'title' : title ,
'result' : result,
'debug' : msg })
this is a snippet from my template
<div class="content">
{{ form.errors }}
{{ form.non_field_errors }}
{% if form %}
<h2>{{ title }}</h2>
<form action="/calc/{{m.id}}" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Calculate" />
</form>
{% if result %}
The Result is <span class="result"> {{ result }} </span>
{% endif %}
</div>
So i get empty braces {} for "%s" % repr(form.errors), form.errors and form.non_field_errors returns nothing. the form posts and I can see the raw data in the request but i keep getting false from is_valid(). why is that ?
EDIT: when checking if the form is bound i also get false. guessing this is the problem. why isn't the form bound after the call for form = MeasureForm(request.POST, measure_id = request.POST.get('measure_id')) ?
** django newbie, Thanks.
Because you're not passing the arguments into the super call. You should do this:
super(MeasureForm,self).__init__(*args, **kwargs)
otherwise the form will never actually be initialised with the POST data.
Edit after comment The answer to that question didn't recommend removing all the arguments from the super call. If you're passing in measure_id you'll simply need to remove it from kwargs beforehand:
def __init__(self, *args, **kwargs):
measure_id = kwargs.pop('measure_id', None)
super(MeasureForm,self).__init__(*args, **kwargs)