Django request with user criteria - django

I would like to get some help about my future process. I would like that users could create his own django request and then get the result.
Up to now, I created django requests in my script but there are static requests :
request1 = Test.objects.all()
or
query_lastname_ID = request.GET.get('q1ID')
query_firstname_ID = request.GET.get('q1bisID')
query_naissance_ID = request.GET.get('q1terID')
if query_firstname_ID and query_lastname_ID and query_naissance_ID :
query_ID_list = Individu.objects.filter(
Nom__icontains=query_lastname_ID,
Prenom__icontains=query_firstname_ID,
VilleNaissance__icontains=query_naissance_ID)
if len(query_ID_list) != 0 :
messages.success(request, 'Miracle .. Vous avez un résultat !')
else :
messages.error(request, "Oh non .. Vous n'avez aucun résultat !")
All of these requests are static.
Now I would like to let the choice to the user between criteria or mathematic operator.
I won't write table fields in my request but the user could have the choice to get what he wants :
one field
two fields
x fields
the mathematic operator (=, >, <, not egal, ...)
comparison between fields
...
User could get a result thanks to a dynamic request. He could create himself Django request.
Is it possible ? I don't find example or documentations about this kind of process :/

You can try create filter as dict, for example:
map_fields_get = {
'Nom': 'q1ID', 'Prenom': 'q1bisID', 'VilleNaissance': 'q1terID'
}
condition_param = 'YOUR_GET_NAME_FOR_CONDITION'
condition_list = ['icontains', 'iexact', 'gt', 'lt']
condition = request.GET.get('condition_param', 'icontains')
if condition not in condition_list:
# add your logic set default or raise
condition = condition_list[0]
qs_f = {}
for get_f, f in map_fields_get.items():
get_val = request.GET.get(get_f, None)
if get_val:
qs_f_key = '%s__%s' % (f, condition)
qs_f[qs_f_key] = get_val
if qs_f:
query_ID_list = Individu.objects.filter(**qs_f)

Related

django filter data and make union of all data points to assignt to a new data

My model is as follows
class Drawing(models.Model):
drawingJSONText = models.TextField(null=True)
project = models.CharField(max_length=250)
Sample data saved in drawingJSONText field is as below
{"points":[{"x":109,"y":286,"r":1,"color":"black"},{"x":108,"y":285,"r":1,"color":"black"},{"x":106,"y":282,"r":1,"color":"black"},{"x":103,"y":276,"r":1,"color":"black"},],"lines":[{"x1":109,"y1":286,"x2":108,"y2":285,"strokeWidth":"2","strokeColor":"black"},{"x1":108,"y1":285,"x2":106,"y2":282,"strokeWidth":"2","strokeColor":"black"},{"x1":106,"y1":282,"x2":103,"y2":276,"strokeWidth":"2","strokeColor":"black"}]}
I am trying to write a view file where the data is filtered based on project field and all the resulting queryset of drawingJSONText field are made into one data
def load(request):
""" Function to load the drawing with drawingID if it exists."""
try:
filterdata = Drawing.objects.filter(project=1)
ids = filterdata.values_list('pk', flat=True)
length = len(ids)
print(list[ids])
print(len(list(ids)))
drawingJSONData = dict()
drawingJSONData = {'points': [], 'lines': []}
for val in ids:
if length >= 0:
continue
drawingJSONData1 = json.loads(Drawing.objects.get(id=ids[val]).drawingJSONText)
drawingJSONData["points"] = drawingJSONData1["points"] + drawingJSONData["points"]
drawingJSONData["lines"] = drawingJSONData1["lines"] + drawingJSONData["lines"]
length -= 1
#print(drawingJSONData)
drawingJSONData = json.dumps(drawingJSONData)
context = {
"loadIntoJavascript": True,
"JSONData": drawingJSONData
}
# Editing response headers and returning the same
response = modifiedResponseHeaders(render(request, 'MainCanvas/index.html', context))
return response
I runs without error but it shows a blank screen
i dont think the for function is working
any suggestions on how to rectify
I think you may want
for id_val in ids:
drawingJSONData1 = json.loads(Drawing.objects.get(id=id_val).drawingJSONText)
drawingJSONData["points"] = drawingJSONData1["points"] + drawingJSONData["points"]
drawingJSONData["lines"] = drawingJSONData1["lines"] + drawingJSONData["lines"]

Struggling with many to many field

I'm trying to create a new product.
Here is my model :
class Product(models.Model) :
door = models.ForeignKey(Door, on_delete=models.CASCADE)
options = models.ManyToManyField(Option)
Here is my views :
def new_product(request, door_id) :
door = get_object_or_404(Door, id=door_id)
checked = request.POST.getlist('checks[]')
c_checked = []
for check in checked :
new_check = get_object_or_404(Option, name=check)
c_checked.append(new_check)
product = Product.objects.create(
door = door,
options = c_checked,
)
product.save()
return render(request, "confirmation.html")
Unfortunately, when I run the server, I get an error saying :
Direct assignment to the forward side of a many-to-many set is
prohibited. Use options.set() instead
Please help me if you have the answer.
.
According to the documentation, you should use add. create method represents one insert in a database but you want to insert multiple records.
def new_product(request, door_id) :
door = get_object_or_404(Door, id=door_id)
checked = request.POST.getlist('checks[]')
c_checked = []
for check in checked :
new_check = get_object_or_404(Option, name=check)
c_checked.append(new_check)
product = Product.objects.create(door=door)
product.options.add(*c_checked)
return render(request, "confirmation.html")

django: Class-based Form has no errors but is not valid. What is happening?

I have a form which is returning False from .is_valid(), but .errors and .non_field_errors() appear to be empty. Is there any other way to check out what might be causing this?
In case it's a problem with my logging code, here it is:
logger.debug('form.non_field_errors(): ' + str(form.non_field_errors()))
logger.debug('form.errors: ' + str(form.errors))
My form code:
class IncorporateForm(forms.Form):
type_choices = (("LTD", "Private company limited by shares"),
("LTG", "Private company limited by guarantee"),
("PLC", "Public limited company"),
("USC", "Unlimited company with share capital"),
("UWS", "Unlimited company without share capital"))
country_choices = (("EW", "England and Wales"),
("CY", "Wales"),
("SC", "Scotland"),
("NI", "Northern Ireland"))
articles_choices = (("MOD", "Model articles"),
("AMD", "Model articles with amendments"),
("BES", "Entirely bespoke articles"))
name = forms.CharField(initial = "[name] limited")
registered_office = forms.CharField(widget=forms.Textarea,
label='Registered office address')
registration_country = forms.ChoiceField(choices=country_choices,
widget=forms.RadioSelect(renderer=SaneRadioField))
company_type = forms.ChoiceField(choices=type_choices,
widget=forms.RadioSelect(renderer=SaneRadioField), initial="LTD")
articles_type = forms.ChoiceField(choices=articles_choices,
initial='MOD',
widget=forms.RadioSelect(renderer=SaneRadioField))
restricted_articles = forms.BooleanField()
arts_upload = forms.FileField(label='Articles to upload')
My view code (to the point where I detect that the form is not valid):
def incorporate_view(request):
form = IncorporateForm()
DirectorsFormset = forms.formsets.formset_factory(OfficerForm, extra=30)
CapitalFormset = forms.formsets.formset_factory(CapitalForm, extra=30)
HoldingFormset = forms.formsets.formset_factory(HoldingForm, extra=30)
AmendsFormset = forms.formsets.formset_factory(ArticlesAmendsForm, extra=50)
if request.method == 'POST':
#bind and validate
form.data = request.POST
guarantee_form = GuaranteeForm(data=request.POST)
directors_formset = DirectorsFormset(prefix='directors', data=request.POST)
capital_formset = CapitalFormset(prefix='capital', data=request.POST)
holding_formset = HoldingFormset(prefix='holding', data=request.POST)
amends_formset = AmendsFormset(prefix='amends', data=request.POST)
save_objects = [] # objects to be saved at the end if there is no error
user_objects = {} # keyed by email
individual_objects = {} # keyed by email?
if(not (form.is_valid() and guarantee_form.is_valid()
and directors_formset.is_valid()
and capital_formset.is_valid() and
holding_formset.is_valid() and
amends_formset.is_valid())):
dbg_str = """
form.is_valid(): %s
guarantee_form.is_valid(): %s
directors_formset.is_valid(): %s
capital_formset.is_valid(): %s
holding_formset.is_valid(): %s
amends_formset.is_valid(): %s
""" % (form.is_valid(), guarantee_form.is_valid(),
directors_formset.is_valid(),
capital_formset.is_valid(),
holding_formset.is_valid(),
amends_formset.is_valid())
logger.debug(dbg_str)
logger.debug('form.non_field_errors(): ' + str(form.non_field_errors()))
logger.debug('form.errors: ' + str(form.errors))
Assigning to form.data does not bind the form — you should pass the data dict when the object is constructed (or look into the code and see which flags are set, but that's probably not documented and therefore not recommended).

Denormalising field in django

I'm finding it difficult to denormalise a field in a django model. I have:
class AnswerSet(models.Model):
title = models.CharField(max_length=255)
num_answers = models.PositiveIntegerField(editable=False, default=0)
answers = models.ManyToManyField(Answer, through='AnswerSetAnswer')
...
class AnswerSetAnswer(models.Model):
answer = models.ForeignKey(Answer)
answer_set = models.ForeignKey(AnswerSet)
...
I want num_answers to contain a count of the number of answers in the set.
If 5 answers are initially associated with the AnswerSet "Food" and I edit one so it becomes associated with the AnswerSet "Colours", how can I recalculate the number of answers in the AnswerSet with "Food"? All the signals only seem to send the new data so I can't just override the save method.
I've tried using the m2m_changed signal, but it never gets called when I edit relationships through the admin form.
Here's my code anyway:
def update_answer_set_num_answers(sender, **kwargs):
"""
Updates the num_answers field to reflect the number of answers
associated with this AnswerSet
"""
instance = kwargs.get('instance', False)
print "no instance" # never gets here
if not instance:
return
action = kwargs.get('action')
print "action: ", action
if (action != 'pre_remove' and action != 'pre_add' and action != 'clear'):
return
reverse = kwargs.get('reverse')
if reverse:
answer_set = instance.answer_set
else:
answer_set = instance.answer_set
num_answers = AnswerSetAnswer.objects.filter(answer_set=answer_set.id).count()
if (action == 'pre_remove'):
num_answers -= int(kwargs.get('pk_set'))
elif (action == 'pre_add'):
num_answers += int(kwargs.get('pk_set'))
elif (action == 'clear'):
num_answers = 0
answer_set.num_answers = num_answers
print 'n a: ', answer_set.num_answers
answer_set.save()
m2m_changed.connect(update_answer_set_num_answers, \
AnswerSet.answers.through, weak=False)
Do you really need to denormalise this? You can calculate it with a simple aggregate:
from django.db.models import Count
answersets = AnswerSet.objects.all().annotate(num_answers=Count('answers')

filter using Q object with dynamic from user?

In my views.py I have a method:
#......
def get_filter_result(self, customer_type, tag_selected):
list_customer_filter=[]
customers_filter = Customer.objects.filter(Q(type__name=customer_type),
Q(active=True),
Q(tag__id=tag_selected))
for customer_filter in customers_filter:
customer_filter.list_authorize_sale_type = sale_type_selected(customer_filter.authorize_sale_type)
list_customer_filter.append(customer_filter)
return list_customer_filter
**My case tag_selected is the checkbox values that user checked
I have a problems with tag_selected(is the list=1,2,3,...) that pass from my url
/?customer_type=TDO&tag=2 ===>filter okay
/?customer_type=TDO&tag=3 ===>filter okay
?customer_type=TDO&tag=2,3 ===>How Can I add And condition in filter?
for example
if len(tag_selected)==1:
customers_filter = Customer.objects.filter(Q(type__name=customer_type),
Q(active=True),
Q(tag__id=tag_selected))
else:
customers_filter = Customer.objects.filter(Q(type__name=customer_type),
Q(active=True),
Q(tag__id=tag_selected[0])
Q(tag__id=tag_selected[1])
Q(tag__id=tag_selected[2])
...
)
This works for both single and multiple conditions:
idseq = request.POST['tag'].split(',')
tag_qs = reduce(operator.or_, (Q(tag__id=x) for x in idseq))
Customers.objects.filter(..., tag_qs)