DRF filter choices by group name - django

Let's say I'm making a media library model, and there are these choices in named groups:
models.py
class MediaLibrary(models.Model):
MEDIA_CHOICES = [
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
)
]
media_type = models.CharField(max_length=50, choices=Media_Choices)
If I make a request through DRF, it would return all the objects which match either "Audio" and "Video".
How can I filter the request so that it only returns objects under the "Audio" group. (Or the "Video" group.)

create a model manger and do filter as follows
class MediaManager(models.Manager):
def video_items(self):
return self.get_queryset().filter(media_type='Video')
---your models here--
objects = MediaManager()
then you can call in your views as MediaLibrary.objects.video_items(), similarly filer audio too.

Related

Django enum named groups

I want a listing to be able to have a specific category, so the seller will choose a general category and then onto a more specific one, for example:
Men's Wear:
Jeans:
Skinny Fit
Slim Fit
Regular Fit
Pants:
Slim Fit
Formal
Casual
Women's Apparel:
Tops:
Tunics
Denim:
Jeans
I tried the named groups like in django docs:
https://docs.djangoproject.com/en/3.0/ref/models/fields/#field-choices-named-groups
MEDIA_CHOICES = [
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
]
But when I tried, it gives the error
product.Listing.category: (fields.E005) 'choices' must be an iterable containing (actual value, human readable name) tuples.
here is my code:
class Listing(models.Model):
CATEGORY = [
('Women\'s Apparel', (
('Dresses', (
('party_dresses', 'Party Dresses'),
)
),
),
),
]
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=255)
description = models.CharField(max_length=255)
new_condition = models.BooleanField()
category = models.CharField(choices=CATEGORY, max_length=255)
why is it showing error ? is it because the enum groups cant be nested more than 1 level ?
thank you

Django retrieve key of group ChoiceField

retrieve key of group ChoiceField
MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
)
class ressource(models.Model):
....
media = models.CharField(max_length=50, choices=MEDIA_CHOICES)
in field media i have vinyl or cd or vhs or dvd...but how retrieve audio,video, unknown ?
You should prove us more details. First of all choices should be iterable object (tuple for example as it's in your case), but your tuple is very complicated in your case (Django can not process this). You should pass something like this as a choices.
choices example (This is good tuple code)
CHOICES = (
('key', 'value') # key will be inserted in database (and validation purposes), and value is just for representation purposes.
)
LANGUAGES = (
('python', 'Python'),
('js', 'JS'),
('ruby', 'Ruby'),
)
Imagine that, you are trying to retrieving object from database.
class ressource(models.Model):
''' This is your model '''
media = models.CharField(max_length=50, choices=MEDIA_CHOICES)
res = ressource.objects.get(pk=1) # retrieve data from database.
print(res.media) # returns string object. you will read actual value of media field
''' But if you want to read all available choices on this field, Django provide as _meta api. You can use it very nice way '''
res = ressource.objects.get(pk=1)
fields = res._meta.fields # This will return tuple-like object.
for field in fields:
if field.name == 'media':
# you want to find "media" field
print(field.choices) # This will return all available choices on your media field
Hope, it helps you. Good luck.

Filter based on children_set count in Django

I am filteren a children set as
ParentModel.objects.all().prefetch_related(
Prefetch(
lookup='childrenmodel_set',
queryset=ChildrenModel.objects.exclude(is_active=False)
)
)
Now each ParentModel object can have a childrenmodel_set but some of these querysets are empty.
How can I exclude those ParentModel objects which has no childrens?
I've thought of:
ParentModel.objects.all().prefetch_related(
Prefetch(
lookup='childrenmodel_set',
queryset=ChildrenModel.objects.exclude(is_active=False)
)
).exclude(childrenmodel_set=None)
or
ParentModel.objects.all().prefetch_related(
Prefetch(
lookup='childrenmodel_set',
queryset=ChildrenModel.objects.exclude(is_active=False)
).aggregate(num_objects=Count(id))
).exclude(num_objects=0)
or
ParentModel.objects.all().prefetch_related(
Prefetch(
lookup='childrenmodel_set',
queryset=ChildrenModel.objects.exclude(is_active=False)
)
).annotate(childrenset_size=Count(childrenset)).exclude(childrenset_size=0)
I could of course check this in the template but I want to do it on database level.
Edit:
Now my code is
self.model.objects.prefetch_related(
Prefetch(
lookup='periods',
queryset=Period.objects.exclude(is_active=False)
)
).exclude(periods__isnull=True)
It removes those objects which has no periods. But if an object has only non-active periods it is still represented in the queryset. How can I make the exclude take the prefetching into account?
Edit 2
My models
class Article:
name = CharField(max_length=100)
class Period:
article = ForeignKey(Article)
is_active = BooleanField(default=True)
ParentModel.objects.exclude(childrenmodel_set__isnull=True)

How do I set a Many-to-Many relation for predefined chocies in Django models?

I have a WorderOrder class that has predefined work order types:
class WorkOrder( models.Model ) :
WORK_TYPE_CHOICES = (
( 'hc', 'Heating and cooling' ),
( 'el', 'Electrical' ),
( 'pl', 'Plumbing' ),
( 'ap', 'Appliances' ),
( 'pe', 'Pests' ),
( 'ex', 'Exterior' ),
( 'in', 'Interior' ),
( 'ot', 'Others' ),
)
work_type = models.CharField( max_length = 2, choices = WORK_TYPE_CHOICES )
vendor = models.ForeignKey( Vendor, null = True, blank = True )
Therefore each order must have one work order type. Later down the road, a vendor can also be assigned to a work order.
I want the Vendor class to have a M2M relationship to the same work order choices in the WorkOrder class. In other words, each vendor are able to do one or many work types. For example, Bob's Plumbing can only do "Plumbing", whereas Solid Home Repair can do "Electrical", "Plumbing", "Exterior", and "Interior".
I understand I can create another table called WorkType and use foreign keys from WorkOrder and a M2M from Vendor, but since I feel I won't be changing the work type choices, I would rather have them predefined in models.py.
Also if I can predefine it in models.py, then I don't have to pre-populate the table WorkType during deployments and upgrades.
Some options for you:
create a model for work_type_choices, instantiate the records (hc, el, etc), then use a manytomany field, or
create a charfield and save CSV values to it (eg: "hc, el"), spliting/joining the value into it's elements as required, or
encapsule the above charfield and functions into a custom field and use that
leverage someone else's snippet, eg:
http://djangosnippets.org/snippets/1200/

ModelForm in template with a grouped choice field

I have a grouped category field. The problem is that I've created a search form, but when I try presente the form to the user in the template, it goes wrong.
models.py
MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
)
category = models.CharField(max_length=20, choices=MEDIA_CHOICES, verbose_name=_(u'Category'))
forms.py (search)
class SearchingForm(forms.Form):
"Search Box"
search = forms.CharField(max_length=100, required=False, label=(_(u'Search')))
music_kind = forms.MultipleChoiceField(choices=MEDIA_CHOICES, required=False,
label=(_(u'Kind')),
widget=forms.CheckboxSelectMultiple(),
)
template.html
{{ form.search }}
{{ form.place_kind }}
I show the form to the user like this, the problem is when I rendered with a browser I have something like this (in each line, it has a checkbox):
(('vinyl', 'Vinyl'), ('cd', 'CD'))
(('vhs', 'VHS Tape'), ('dvd', 'DVD'))
Unknown
I have delete the 'widget=forms.CheckboxSelectMultiple()' attribute it goes right, but I don't have a checkboxes. So, How I can do it with checkbox fields?
I think you have a data type mismatch here. You're wanting to store multiple values in a single CharField. Sure, you could save a dictionary of key-value pairs in there, but then you'd have to parse it back out into selections, and that's a huge pain.
I would move your MEDIA_CHOICES to a database table, and then in your SearchingForm, you can do a CheckboxSelectMultiple, and the form will behave as expected.
I'm not sure, but I wonder if choice groups are only for select boxes (not checkboxes).