Django can't eliminate duplicated entries with set (mysql) - python

I have a list a on the code, and i want to eliminate duplicated entries.
I saw a very clean method here: http://love-python.blogspot.pt/2008/09/remove-duplicate-items-from-list-using.html
i am using mysql
But when i acesss the page i get this error: 'list' object has no attribute 'all' i can't figure where this is coming from!
forms.py:
from testApp.models import Ficha_medico
from django.forms import ModelForm
from django import forms
class MenuForm(ModelForm):
a = Ficha_medico.objects.values_list('zona', flat=True)
a = list (set(a))
zona = forms.ModelChoiceField(queryset=a)
class Meta:
model = Ficha_medico
Any help appreciated

The error message tells you where it is coming from.
A list is not a queryset. You can't pass it as the queryset parameter of a field.
To eliminate duplicates in a queryset, use .distinct().

.values_list() returns a list object, not a queryset.
Apparently, something like this would work if you're using PostgreSQL:
a = Ficha_medico.objects.distinct('zona')
For others, I suspect there's a better way, but this would work:
class MenuForm(ModelForm):
items = Ficha_medico.objects.values_list(('id', 'zona'), flat=True)
# get a single 'id' per 'zona'
# --> since we don't know how many there are cycle through all
# --> note: this will overwrite existing values, but doesn't seem to matter.
uniques = {z: i for i, z in items}
# re-query to retrieve only the necessary number of unique zona values
qs = Ficha_medico.objects.filter(id__in=uniques.values())
zona = forms.ModelChoiceField(queryset=qs)
class Meta:
model = Ficha_medico

Related

Django admin model query url string on NOT EQUALS

I have a simple Django ForeignKey relationship between two models in postgreSQL. The logic here is the Sample object can optionally have a foreign key into a type of sample control.
from django.contrib.postgres.fields import CICharField
from django.db import models
class Sample(models.Model):
controls_applied = models.ForeignKey(SampleControl, null=True,
blank=True,
on_delete=models.SET_NULL)
class SampleControl(models.Model):
id = CICharField(max_length=200, primary_key=True)
On the admin changelist for Sample, I am trying to create filter that queries all or none of Samples that have a specific control (in this case, we'll use a SampleControl with id='runcontrol'). I'm trying to craft the specific URI string to append to my changelist url as I have other filters I'm trying to run in conjunction.
To get all samples with controls_applied= 'runcontrol', I can simply append the following string to my URL (notice the reference to the id of the foreign key):
?controls_applied__id=runcontrol
But if I want to get all samples that are not run control, it's more complicated. Wasn't sure what to do, so I decided to use 'startswith', which has a convenient 'notstartswith' companion that will do the inverse. When I use this, I see that the following works:
?controls_applied__id__startswith=runcontrol
However, the inverse
?controls_applied__id__notstartswith=runcontrol
gives me an error: Unsupported lookup 'notstartswith' for CICharField or join on the field not permitted, perhaps you meant startswith or istartswith?
Which leads to me the simple question: is there a way to specify NOT EQUALS in the query string of the URL on Django's admin site? Thank you!
I don't think admin URLs are capable of representing an exclude queryset filter, unless you create your own SimpleListFilter.
Try this in your admin.py:
class WithoutControlListFilter(admin.SimpleListFilter):
title = ('Without Control')
parameter_name = 'without_control'
def lookups(self, request, model_admin):
return (
('runcontrol', ('Run Control')),
)
def queryset(self, request, queryset):
return queryset.exclude(controls_applied=self.value())
class SampleAdmin(admin.ModelAdmin):
list_filter = (WithoutControlListFilter,)
There is a bit of info about admin filters in the Django ModelAdmin docs.

Django annotate - get attribute of all related objects

I have such a models:
# models.py
class A(Model):
...
class B(Model):
parent = ForeignKey(A)
comments = ForeignKey(Comments)
class Comments(Model):
title = CharField(...)
How, using annotate method of queryset, I can get all titles of Bs' comments related to some A queryset?
I tried:
result = A.object.all().annotate(b_titles=F("b__comments__title"))
but it returns only first object.
FilteredRelation also didnt help (FilteredRelation's condition doesn't support nested relations)
I solved this problem with ArrayAgg (https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/aggregates/)
- available only using Postgres.

Django queryset filter by post variable

I am trying to do a queryset filter using Django. I have Coupon objects with a code, which is a CharField. I want to find all Coupon objects with a matching code.
My model:
class Coupon(models.Model):
code = models.CharField(max_length=50)
... other fields
My view:
# This method returns the queryset
Coupon.objects.filter(code = "abc123")
# This part of the code is not working the way I want to
couponCode = str(request.POST.get("code"))
Coupon.objects.filter(code = couponCode)
I have ensured that the POST variable is "abc123" but I am still getting an empty queryset in the second query.
Just use
couponCode = request.POST['code']
instead of
couponCode = str(request.POST.get("code"))
Remove the str() part. Leave it only as:
couponCode = request.POST.get("code"),
then you could do:
Coupon.objects.filter(code=couponCode)
Hope this helps.

'.....' object is not iterable in django

I have 3 models: User, Choice, Card. Each user will look at the same set of 10 cards and decides each one is important or not.
Here are how I define the classes and their relationship
In models.py:
class Choice(models.Model):
user = models.ForeignKey(User)
card = models.ManyToManyField(Card)
is_important = models.NullBooleanField()
class Card(models.Model):
card_number = models.IntegerField(primary_key=True)
content = models.TextField(null=False)
In views.py
(I try to save the choice for the card from the user. )
def listings(request):
user = request.user
choice = Choice.objects.create(user=user, is_important = True)
choice.card= Card.objects.get(1)
However, I got this error
'Card' object is not iterable
Could you please show me where the error is?
Many thanks!
You can add object against many to many field like this
card = Card.objects.create(card_number=any_number, content='abc')
choice.card.add(card)
First, it looks like you forgot pk= in your first .get() argument: Card.objects.get(pk=1)
Second, Choice.cards is a ManyToManyField that expects a list of items and not one in particular. You should set it through:
choice.card.set(Card.objects.filter(pk=1))
Please note that direct assignment with = will be deprecated from Django 1.10 and deleted in Django 2.0
.filter() will return a QuerySet (which is iterable). I think you wanted a ForeignKey instead of a M2M field, in which case your code would work (with the additional pk=).
In your function:
def listings(request):
user = request.user
choice = Choice.objects.create(user=user, is_important = True)
choice.card= Card.objects.get(1)
The following line is trying to fetch the Card object. However, we need to specify which card to be fetched.
If using an id, query it as:
choice.card= Card.objects.get(pk=1)
or else using list of ids:
choice.card = Card.objects.filter(pk__in=[12,22])
If using card_number field:
choice.card= Card.objects.get(card_number=1)
or else using list of card_numbers:
choice.card = Card.objects.filter(card_number__in=[12,22])

Django: exclude User list from all Users

I asked a similar question today (Django: exclude User list from all Users ), the sollution was to write a symmetrical query. Since I changed my models with a many-to-many relation, this solution isn't valid anymore.
How can I exclude a list of users from user instances? With this method:
class Shift(models.Model):
shift_location = models.CharField(max_length=200)
users = models.ManyToManyField(User)
def get_shift_users(self):
return self.users.all()
def get_other_users(self):
return User.objects.all().exclude(self.users.all())
I get the error: AttributeError: 'User' object has no attribute 'split'
You need to use the in operator:
User.objects.exclude(id__in=self.users.all())
By using an unevaluated queryset (self.users.all()), it is transformed in a subquery, so the result will be fetched in a single query.
Maybe something like this:
User.objects.all().exclude(id__in=[u.id for u in self.users.all()])

Categories

Resources