Exclude is not working on djnago queryset - django

usr_all_friends_shw = Friend.objects.filter(profile_id__in = request.user.profile.friends.all())
uzr_al_cnfr_frn = FriendRequestSave.objects.filter(receiver_request=request.user.profile)
sugges= Friend.objects.exclude(profile_id__in=usr_all_friends_shw).exclude(profile_id=request.user.pk)
for i in uzr_al_cnfr_frn:
bdhc63=Friend.objects.filter(profile_id=i.sender_request.pk)
print(bdhc63)
sugestion_aftr=sugges.exclude(profile_id__in=bdhc63)
It does not show any error but still not excluding elements

Related

How to fix Django N+1 problem when you need to get data from a set of objects

I created a function and I wrote a query that results in N+1 Problem how to fix it
code
sponsors = CustomUser.objects.filter(user_type = 2, is_deleted = False)
for s in sponsors:
s.sponsor_detail = Sponsor.objects.get_or_create(user = s, is_deleted = False)
Would be nice if you included the models, but I guess sponsor_details is a ForeignKey. In this case you should use select_related:
sponsors = (CustomUser.objects
.filter(user_type = 2, is_deleted = False)
.select_related('sponsor_detail'))

For each item update database

I'm a total beginner with Python/Django and trying to understand why this isn't working. I have a function that contains a for loop, doing some logic and then updating a model. but when I have more than 1 item in the loop I get a UNIQUE constraint failed: app_token.token_name error.
So I think I'm misunderstanding how the loop is working?
function
tokens = Token.objects.all()
for item in tokens:
if item.token_contract_address is not None:
token = Token.objects.get(pk=item.id)
parameters = {
'address':token.token_contract_address
}
session = Session()
session.headers.update(headers)
response = session.get(url, params=parameters)
resp = json.loads(response.text)
token_id = (resp['data'][next(iter(resp['data']))]['id'])
logo = (resp['data'][next(iter(resp['data']))]['logo'])
url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest'
parameters = {
'id':token_id
}
session = Session()
session.headers.update(headers)
response = session.get(url, params=parameters)
id = str(token_id)
price = (json.loads(response.text)['data'][id]['quote']['USD']['price'])
market_cap = (json.loads(response.text)['data'][id]['quote']['USD']['market_cap'])
change = (json.loads(response.text)['data'][id]['quote']['USD']['percent_change_24h'])
r = Token.objects.update(token_capture_date = formatedDate, token_price = price, token_name=item.token_name )
I'm expecting the this Token.objects.update(token_capture_date = formatedDate, token_price = price, token_name=item.token_name ) to update the model based on the item loop?
The model is very simple:
class Token(models.Model):
token_name = models.CharField(max_length=50, blank=False, unique=True)
token_slug = models.CharField(max_length=50, blank=True,null=True)
token_price = models.FloatField(blank=True,null=True)
token_capture_date = models.DateField(blank=True,null=True)
token_contract_address = models.CharField(max_length=50, blank=True,null=True)
def __str__(self):
return str(self.token_name)
I'm using the update on the objects and have tried removing the token_name, and tried using token.token_name
If I remove token_name= it updates both items in the database with the same values? which makes me think its this line r = Token.objects.update(token_capture_date = formatedDate, token_price = price, token_name=item.token_name ) do i need to apply some kinda of filter?
Thanks
I believe that by calling Token.objects.update() you actually end up trying to update all Token objects. Since token_name has to be unique, and you are giving it the same name as another Token object it throws that error.
Since you are already in a for loop, you can simply update the token that is currently being processed.
My suggestion would be to use this code instead:
item.token_capture_date = formattedDate
item.token_price = price
item.save()
This will make it so that the current token object which is being processed in the for loop has its respective field values updated and saved in the database.
Also, this line is unnecessary: token = Token.objects.get(pk=item.id) as we already have access to the token through the looping variable item.
Do let me know if this helps!

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")

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)