django-filter | first filter "------" - django

I want to rename first filter (all), now its like "--------", question is: how to let it name
filters.py:
class DoctorsFilter(django_filters.FilterSet):
category = ModelChoiceFilter(queryset=DoctorCategory.objects.all().order_by('category'),
widget=forms.Select(attrs={"onchange":"submit();"}),
label='')
class Meta:
model = Doctors
fields = ['category']

According to the docs you can set
FILTERS_EMPTY_CHOICE_LABEL = "(all)"
in settings.py

Related

how to populate drop down choice from data base in django form

I want to try populating fields from the database in Django form, but it's showing me blankly.
Can anyone give me an idea?
Here I am sharing my code.
class circleform(forms.ModelForm):
class Meta:
model = curd
fields = ['Zone','Circle','circle_code','circle_address']
widgets = {
'Zone':forms.Select(attrs = {'class':'form-control'}),
'Circle':forms.TextInput(attrs = {'class':'form-control'}),
'circle_code':forms.TextInput(attrs = {'class':'form-control'}),
'circle_address':forms.TextInput(attrs = {'class':'form-control'}),
}
I think you could use a field overriding like
class YourForm(forms.ModelForm):
your_foreign_key_field_name = forms.ModelChoiceField(queryset=YourChoiceModel.objects.all())
class Meta:
....
or in case you just want a form that reflect all your model's fields, try using Admin
https://docs.djangoproject.com/en/4.1/intro/tutorial07/
If you are looking for a field that will populate your query based on a query then ModelChoiceField is what you are looking for. You can use it like that
class circleform(forms.ModelForm):
your_field = ModelChoiceField(queryset="you query here to populate choice field")
# ...
but if you have some hard-coded choices that you want to populate then you can pass a choices=YOUR_CHOICES_TUPLE like that.
class circleform(forms.ModelForm):
class Meta:
model = curd
fields = ['Zone','Circle','circle_code','circle_address']
YOUR_CHOICES = (
('', 'Select your zone'),
('1', 'First'), #First one is the value of the select option and the second is the displayed value in the option
('2', 'second'),
)
widgets = {
'Zone':forms.Select(attrs = {'class':'form-control'}, choices=YOUR_CHOICES), # new
}

Django 1.9 How do you filter child's child's model with or statement?

I have a parent model Catalog and its child model Product and Product's child model Options.
Catalog and Product's relationship is OneToOne and Product and Options's relationship is OneToMany
I'd like to filter if one of Options is met a condition, return Catalog model
here is my code below
class Catalog(models.Model):
product = models.ForeignKey(models.Product)
class Product(models.Model):
objects = ProductManager()
class ProductOptions(models.Model):
product = models.ForeignKey(Product, related_name = 'options')
class ProductManager(models.Manager):
def get_queryset(self):
queryset = super(ProductManager, self).get_queryset()
queryset = queryset.prefetch_related('options')
return queryset
and What I've tried so far is
this query works fine without or statement
catalog_query = models.Catalog.objects.all()
catalog_query = catalog_query.filter(product__options__date=datetime(2018,10,24)
but when i put or statement, it returns duplicated Catalog data
catalog_query = models.Catalog.objects.all()
catalog_query = catalog_query.filter(product__options__date=datetime(2018,10,24) | catalog_query.filter(product__quantity_limit=True)
You need "Q object":
https://docs.djangoproject.com/pl/2.1/topics/db/queries/#complex-lookups-with-q-objects
example from documentation:
Q(question__startswith='Who') | Q(question__startswith='What')
so your example will look like that:
from django.db.models import Q
catalog_query = catalog_query.filter(
Q(product__options__date=datetime(2018,10,24))
| Q(catalog_query.filter(product__quantity_limit=True))
Use ".distinct()" on queryset to remove duplicates:
https://docs.djangoproject.com/pl/2.1/ref/models/querysets/#django.db.models.query.QuerySet.distinct

Fetching nested objects with Django REST framework

I am attempting to fetch nested objects but not quite sure how to achieve this. My model is as shown:
class Brand(models.Model)
name = models.CharField(max_length=128)
class Size(models.Model)
name = models.CharField(max_length=128)
class Brand_Size(models.Model)
brand = models.ForeignKey(Brand)
size = models.ForeignKey(Size)
class Brand_Size_Location(models.Model)
location = models.ForeignKey(Location)
brand_size = models.ForeignKey(Brand_Size)
I filter objects in Brand_Size_Location by location which can occur 1..x. I want my serializer to output the results in terms of the model Brand (BrandSerializer). Since my resultset can be 1..x and furthermore the occurrence of Brand can be duplicates i would like to eliminate these aswell at the same time.
You should be able to do this fairly easily by including a serializer field in your BrandSerializer:
class BrandSerializer(serializers.ModelSerializer):
brand_sizes = BrandSizeSerializer(
source='brand_size_set',
read_only=True
)
class Meta:
model = Brand
fields = (
'id',
...add more fields you want here
'brand_sizes')
You can simlarly create the brand size serializer to nest the locations
Filtering on this relationship occurs in the view and will need a custom filter. Here's a basic example using a ListView:
class BrandFilter(django_filters.FilterSet):
location = django_filters.ModelMultipleChoiceFilter(
queryset=Brand_Size_Location.objects.all(),
name='brand_size__brand_size_location__location'
)
location_name = django_filters.CharFilter(
name='brand_size__brand_size_location__location__name'
)
class Meta:
model = Brand
fields = [
'location',
'location_name'
]
class BrandList(LoginRequiredMixin, generics.ListCreateAPIView):
model = Brand
serializer_class = BrandSerializer
filter_class = BrandFilter
You can then use query parameters to filter on the URL like:
http://somehost/api/brands/?location=42
which uses a PK to filter, or with the location name (assuming you have a name field in the Location model):
http://somehost/api/brands/?location_name=Atlantis

Django: Change field label in admin doesn't work

Unfortunately, I'm still using django 1.4 and the verbose_name doesn't work for foreign keys.
It is there a way to change the label of a foreign key. For now, it is not working:
class ProductVariant(models.Model):
product = models.ForeignKey(TestProduct, verbose_name='test product', on_delete=models.PROTECT)
ProductVariant
class ProductVariantForm(forms.ModelForm):
product = forms.ModelChoiceField(queryset=TestProduct.objects.order_by("product__article_code"))
test_software = forms.ModelChoiceField(queryset=TestSoftware.objects.order_by("name"))
class Meta:
model = ProductVariant
class ProductVariantAdmin(admin.ModelAdmin):
fields=["product", "test_software", "test_variables", "name", "description"]
list_display = ("name", "product_name", "test_software_name", "test_variables", "description")
search_fields = ["name"]
form = ProductVariantForm
I hope you can help me.
Thanks in advance!
verbose_name should work with Django 1.4 according to the 1.4 docs.
I think because you're overriding the field in the form it's not using the verbose name for the label. What you could do is set the label on the ModelChoiceField.
class ProductVariantForm(forms.ModelForm):
product = forms.ModelChoiceField(label="Test Product", queryset=TestProduct.objects.order_by("product__article_code"))
test_software = forms.ModelChoiceField(queryset=TestSoftware.objects.order_by("name"))
class Meta:
model = ProductVariant
I'm not quite sure how to use the model's verbose name on the field though, so you might have to define it twice.

Specifying a FilterSet for Django-rest-framework

The tutorial said:
class ProductFilter(django_filters.FilterSet):
min_price = django_filters.NumberFilter(lookup_type='gte')
max_price = django_filters.NumberFilter(lookup_type='lte')
class Meta:
model = Product
fields = ['category', 'in_stock', 'min_price', 'max_price']
but when I try to do this, I get an error:
FieldError: Cannot resolve keyword u'min_price' into field. Choices are: cantidad, datetime, enlace, id, id_fila, nivel
min_price is not in my models, but I need to create a new parameter. (it is an example)
really I need to filter dates.
See the django-filter documentation.
Since your min_price and max_price filters don't have the same name as the model field they refer too, you need to provide the name argument.
class ProductFilter(django_filters.FilterSet):
min_price = django_filters.NumberFilter(name='price', lookup_type='gte')
max_price = django_filters.NumberFilter(name='price', lookup_type='lte')
class Meta:
model = Product
fields = ['category', 'in_stock', 'min_price', 'max_price']