Django - Detecting Value of Field in Model - Views - django

I need to loop through all field objects of a model in Django. Once I look through I need to detect if in any of the entries of data this specific field(type) is equal to "Date1". If it is I need it to send a variable(val) that is a string equal to "True" to the Django templates. I have everything set and it seems simple and it seems like it should work. On its own, the val can send a value to the template when it is not in an if statement and the for loop also properly works. Even when "Date1" exists as a value in the type field of an entry in the model "Field_Repo1" the val isn't sent and the if statement is never iterated through(I know this by using prints). No matter what the if statement is never run through. Code Below. Thanks in advance.
context = {}
context['Field_Repo1'] = Field_Repo1.objects.filter(user=response.user)
for type1 in Field_Repo1.objects.values_list('type'):
if type1 == "Date1":
val = "True"
context['val'] = val
print(val)
print(AHHHHHHHHHHHH)
if response.method == 'POST':
form = Field_Repo1_Form(response.POST, response.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.user = response.user
instance.save()
response.user.Field_Repo1.add(instance)
return redirect('repo1')
else:
form = Field_Repo1_Form()
context['form'] = form
return render(response, 'sheets/add_fields/repo1_add_field.html', context)

The values_list() function returns a queryset of tuples. The statement in your for loop if type1 == "Date1": is trying to compare equality between "Date1" and a tuple, which will never be true. The tuples in the query set all are of length 1 since you only passed a single field to the values_list() function, so you should be able to do if type1[0] == "Date1": for your comparison.

Related

how to add element in django list

I'm confused with how django adds elements to a list. consider the following:
def add(request):
if request.method == "POST":
form = NewTaskForm(request.POST)
if form.is_valid():
task = form.cleaned_data["task"]
request.session['tasks'].append(task)
# request.session['tasks'] += [task]
return HttpResponseRedirect(reverse("tasks:index"))
else:
return render(request, "tasks/add.html",{
"form": form
})
return render(request, "tasks/add.html",{
"form": NewTaskForm()
})
if we add a print statement after request.session['tasks'].append(task) we get a list:
['check email']
we also get the same list if we comment the append line and use the correct way with +=
However, on the redirect to task/index the first way shows an empty list and the second way shows the list that's expected. Why? Whats going on?
Django only saves the session data and sends to client if it has been assigned or deleted. Like in your second example:
request.session['tasks'] += [task]
If you are updating the information inside your session data, it will not recognize the change and won't update it, like when you append some data to the list that is assigned to the 'tasks' key. In this case you need to explicitly tell Django that you modified the session data using:
request.session.modified = True

Can you use a Django form multiple times in one view?

I have a Django view that uses one form multiple times. The form is just a boolean field form that is supposed to initialize to True but then the user can decide to uncheck the boxes or not.
The problem I'm having is that the all of the fields evaluate to True no matter what the user leaves checked. Is this a problem with using the same form multiple times, or did I mess something else up?
The form looks like this:
class DataTypeForm(forms.Form):
def __init__(self,*args,**kwargs):
section_label = kwargs.pop('section_label')
initial_value = kwargs.pop('initial_value')
super(DataTypeForm,self).__init__(*args,**kwargs)
self.fields['dataType'].label=mark_safe(section_label)
self.fields['dataType'].initial=initial_value
self.fields['dataType'].required=False
dataType = forms.BooleanField(required=False)
This is the view:
def Manual_Request(request):
form_dict = {}
arg_dict = {}
message = message = {'last_url':'Nominal_Request'}
if request.method == 'POST':
logger.info("Query submitted, beginning query results render for:")
form_NOM = DataTypeForm(request.POST or None,section_label="ENG_NOM",initial_value=True)
form_DDM = DataTypeForm(request.POST or None,section_label="SCI_DDM",initial_value=True)
form_RAW = DataTypeForm(request.POST or None,section_label="SCI_RAW",initial_value=False)
if form_NOM.is_valid():
NOM = form_NOM.cleaned_data['dataType']
arg_dict.update({'ENG_NOM':str(NOM)})
logger.info("ENG_NOM: {val}".format(val=NOM))
if form_DDM.is_valid():
DDM = form_DDM.cleaned_data['dataType']
arg_dict.update({'SCI_DDM':str(DDM)})
logger.info("SCI_DDM: {val}".format(val=DDM))
if form_RAW.is_valid():
RAW = form_RAW.cleaned_data['dataType']
arg_dict.update({'SCI_RAW':str(RAW)})
logger.info("SCI_RAW: {val}".format(val=RAW))
return Request_Results(request,args_dict)
else:
logger.info("Rendering query page")
form_NOM = DataTypeForm(section_label="ENG_NOM",initial_value=True)
form_DDM = DataTypeForm(section_label="SCI_DDM",initial_value=True)
form_RAW = DataTypeForm(section_label="SCI_RAW",initial_value=True)
form_dict.update({'form_NOM':...etc})
return render(request,'InterfaceApp/COMMRequest_Manual.html',form_dict)
Help much appreciated!
I haven't run your code, but my best guess is that yes, it's a problem with using the same form multiple times in the same view. The reason? All of your <input type="checkbox" name="..." ... /> tags will have the same name, 'dataType'. The user's browser knows nothing of your back-end, and will just send, for example, dataType=on&dataType=on as POST data for the three fields if two are checked and one is not.
Seeing the problem here? How is django supposed to know which of those dataType fields are for your NOM, DDM, or RAW forms? It can't know.
You should be able to solve this using form prefixes. In short, there's a kwarg that you can pass to a form's __init__() that will cause a prefix to be added to all of the form items in the rendered HTML. So, for example:
form_NOM = DataTypeForm(request.POST or None, section_label="ENG_NOM",
initial_value=True, prefix="NOM")
form_DDM = DataTypeForm(request.POST or None, section_label="SCI_DDM",
initial_value=True, prefix="DDM")
form_RAW = DataTypeForm(request.POST or None, section_label="SCI_RAW",
initial_value=False, prefix="RAW")
Hope that helps!
This is exactly what Django formsets are for. They allows you to create a set of the same type of form. It handles prefixes, and adds a management form so that Django doesn't get confused as to what data comes from what form.
https://docs.djangoproject.com/en/1.8/topics/forms/formsets/

How to cast Django form to dict where keys are field id in template and values are initial values?

I have a huge django form and I need to create dict where keys are field id in template and values are initial values?
Something like this:
{'field1_id_in_template': value1, ...}
Does somebody know how do that?
I can add prefix 'id_' for each field name in form.fields dictionary but I can have a problem if somebody change id for widget.attrs
This is method of CBV:
def post_ajax(self, request, *args, **kwargs):
form = ChooseForm(request.POST, log=log)
if form.is_valid():
instance = form.save()
inst_form = InstanceForm(instance=instance, account=request.user)
fields = {}
for name in inst_form.fields:
if name in inst_form.initial:
fields[inst_form.auto_id % name] = inst_form.initial[name]
return HttpResponse(
json.dumps({'status': 'OK','fields':fields},
mimetype='appplication/json'
)
assert False
And this a reason why I do that:
With this response I can write something like this on client. Now I don't need to manualy initialize all fields on the page
function mergeFields(data) {
for(var id in data) {
$("#"+id).val(data[id]).change();
}
}
Originally added to the question body itself reference.
If you have the auto_id set to True then you can get the id with form_object_instance.field_name.auto_id. With that in mind you can create your dict by iterating over the form object.
I am just wondering why you would need to do such a processing as the form object is usually used to encapsulate such behaviors...
you can try getattr.
For example, you have a known key list as
['field1_id_in_template', 'field2_id_in_template', ...]
Then:
my_values = dict()
for key in key_list:
value = getattr(your_form, key)
# now do something with it
my_values[key] = deal_with(value)

Setting Initial in a ModelFormset

According to the documentation providing initial values for fields that are bound to a model is not possible.
In my model form though I have created an additional unbound field:
class DealCForm(ModelForm):
attach_deal_conversation = forms.BooleanField(required=False, initial=False)
Hence I would like to set this value if certain conditions are met.
View:
deal_formset = modelformset_factory(Deal, form=DealCForm, extra=0)
if (request.POST)
pass
else:
opendeal_formset = deal_formset(queryset=formset_query)
variables = RequestContext(request, {'opendeal_formset' : opendeal_formset)
return render_to_response('conversation.html', variables)
In the view, just before sending it to the template, I have set the value directly, however it doesn't work:
for dfm in deal_formset:
for odfm in opendeal_formset:
if dfm.pk == odfm.pk:
odfm.attach_deal_conversation = True;
But it doesn't work. ANy idea how to set the initial value for an unbound field?
Many Thanks
This runs for me:
for form in opendeal_formset:
form.fields['attach_deal_conversation'].initial=True

Best way to handle request variables in Django

I have a form 'in the wild' that takes many different variables - which may or may not be populated.
try:
app_version = request.REQUEST["appVersion"]
except:
app_version = ''
try:
app_name = request.REQUEST["appName"]
except:
app_name = ''
try:
app_code_name = request.REQUEST["appCodeName"]
except:
app_code_name = ''
Is there a tighter way to accomplish this?
app_version = request.REQUEST.get("appVersion", "")
get(key, default) is a method implemented on Python dicts. If the key exists in the dictionary, its value is returned; if the key does not exist, the specified default value is returned. In Django, request objects are dictionary-like objects, so get is also defined for them in the same manner.
If these variables are intended to populate a form, then you can safely pass the request.POST object directly into the form constructor.
if request.method == 'POST':
form = MyForm(request.POST)
The form will automatically pass the correct values to the correct form fields and use defaults for keys that don't exist and will still create blank fields for missing keys (see addendum).
If you are trying to process a form, it is still better to create a form object as above, and read out the values from that object.
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# You may process these variables here
print form.appVersion
print form.appName
print form.appCodeName
Remember, validation code is best placed in the form class as well. That way, if form.is_valid() returns True, then you know you have a clean dataset to work with.
Note: Django docs recommend using request.POST or request.GET directly rather than the amalgamated variable request.REQUEST, as it is more explicit.
Addendum:
It is important to understand the difference between bound and unbound forms in this case. If you create an unbound form with form = MyForm(), then when the form is instantiated, it will fill in all fields with the initial property of each field (if it exists). For example, with this code:
from django import forms
class MyForm(forms.Form):
appVersion = forms.CharField(initial='1.0')
appName = forms.CharField()
appCodeName = forms.CharField()
the form will be initialized with appVersion having a value of '1.0'. However, if you bind a POST request to a form like this: form = MyForm(request.POST), then the initial properties are ignored. That means if the POST dict does not include an appVersion key, then that field will be left blank. As long as the field is not required, your form will still validate, and you can modify form.appVersion in the view after validation.
If you have many fields, a more compact version might be:
defaults = { 'field1' : 'val1', 'field2' : 'val2', ...}
defaults.update(request.POST)