Creating a Dynamic Choice Field

Creating a dynamic choice field

you can filter the waypoints by passing the user to the form init

class waypointForm(forms.Form):
def __init__(self, user, *args, **kwargs):
super(waypointForm, self).__init__(*args, **kwargs)
self.fields['waypoints'] = forms.ChoiceField(
choices=[(o.id, str(o)) for o in Waypoint.objects.filter(user=user)]
)

from your view while initiating the form pass the user

form = waypointForm(user)

in case of model form

class waypointForm(forms.ModelForm):
def __init__(self, user, *args, **kwargs):
super(waypointForm, self).__init__(*args, **kwargs)
self.fields['waypoints'] = forms.ModelChoiceField(
queryset=Waypoint.objects.filter(user=user)
)

class Meta:
model = Waypoint

Django + Forms: Dynamic choices for ChoiceField

Why not pass the choices in from the view when you instantiate the form?

e.g.

Form:

class FooForm(forms.Form):
def __init__(self, foo_choices, *args, **kwargs):
super(FooForm, self).__init__(*args, **kwargs)
self.fields['foo'].choices = foo_choices

foo = forms.ChoiceField(choices=(), required=True)

View:

... 
bars = request.session['bars']
foo_list = []
for bar in bars:
foo_list.append((bar['id'], bar['name']),)
form = FooForm(foo_list)
...

django Choice list (dynamic choices)

In that case, you should not make use of a CharField or some other field with choices, but use a ForeignKey [Django-doc].

For example:

class Category(models.Model):
category = models.CharField(max_length=128, unique=True)

def __str__(self):
return self.category

class MyModel(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)

If you construct a ModelForm, it will use by default a ModelChoiceField [Django-doc], and the default widget is a dropdown with the Category options.

If you want to select multiple Categorys, you should use a ManyToManyField [Django-doc]:

class Category(models.Model):
category = models.CharField(max_length=128, unique=True)

def __str__(self):
return self.category

class MyModel(models.Model):
categories = models.ManyToManyField(Category)

In a filter, you can then use a ModelMultipleChoiceFilter [readthedocs]:

class MyModelFilter(django_filters.FilterSet):
categories = django_filters.ModelMultipleChoiceFilter(
queryset=Category.objects.all()
)
class Meta:
model = MyModel
fields = ['categories']

But normally, without specifying anything that is the default field it will use.

You can alter the widget to a CheckboxSelectMultiple [Django-doc] to work with a sequence of checkboxes:

class MyModelFilter(django_filters.FilterSet):
categories = django_filters.ModelMultipleChoiceFilter(
queryset=Category.objects.all(),
widget=forms.CheckboxSelectMultiple()
)
class Meta:
model = MyModel
fields = ['categories']

filter ChoiceField dynamically based on another field

thanks a lot to Abdul Aziz Barkat who in his comment posted a link to a perfect tutorial.
https://simpleisbetterthancomplex.com/tutorial/2018/01/29/how-to-implement-dependent-or-chained-dropdown-list-with-django.html

Using dynamic Choice Field in Django

You can populate them dynamically by overriding the init, basically the code will look like:

class NewForm(forms.Form):
def __init__(self, choices, *args, **kwargs):
super(NewForm, self).__init__(*args, **kwargs)
self.fields["choices"] = forms.ChoiceField(choices=choices)

NewForm(my_actual_choices) or NewForm(my_actual_choices, request.POST, request.FILES) etc.

Python requests - print entire http request (raw)?

Since v1.2.3 Requests added the PreparedRequest object. As per the documentation "it contains the exact bytes that will be sent to the server".

One can use this to pretty print a request, like so:

import requests

req = requests.Request('POST','http://stackoverflow.com',headers={'X-Custom':'Test'},data='a=1&b=2')
prepared = req.prepare()

def pretty_print_POST(req):
"""
At this point it is completely built and ready
to be fired; it is "prepared".

However pay attention at the formatting used in
this function because it is programmed to be pretty
printed and may differ from the actual request.
"""
print('{}\n{}\r\n{}\r\n\r\n{}'.format(
'-----------START-----------',
req.method + ' ' + req.url,
'\r\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
req.body,
))

pretty_print_POST(prepared)

which produces:

-----------START-----------
POST http://stackoverflow.com/
Content-Length: 7
X-Custom: Test

a=1&b=2

Then you can send the actual request with this:

s = requests.Session()
s.send(prepared)

These links are to the latest documentation available, so they might change in content:
Advanced - Prepared requests and API - Lower level classes



Related Topics



Leave a reply



Submit