django: display selected choices in MultipleChoiceField - django

I have to address a ticket of code someone else wrote.
The form:
class MultiForm(forms.Form):
agencies = forms.MultipleChoiceField(
choices = AGENCY_TYPE,
widget = CheckboxSelectMultipleNoLi,
required=False)
This all works fine.
I can display the form easily:
form = MultiForm()
However, I can't see the the checked elements on the form.
The data is in a dedicated table:
Agency.objects.filter(application=application)
That's just referring to a table:
note | application_id | type | id
------+----------------+-----------+------
where all checked elements will have an entry and their value will be type.
(in other words all Agency elements of an application will have a row).
So when the data is created, it's in a registration form, thus it doesn't get displayed again, it's just one time when the user registers.
How can I display the checked elements (I am showing the form in another part of the app)?

This post put me on track to find the solution:
Set initial value of checkbox dynamically
data = Agency.objects.filter(application=application)
selected = []
for a in data:
selected.append(a.type)
form = MultiForm(initial={'agencies':selected})

Related

How to get the selected foreign key's value?

Models:
class Item(models.Model):
name = [...] # unique
quantity = [..integer_field..]
class Sales(models.Model):
sold_to = [...]
sold_item = foreign key to Item
sold_quantity = [..integer field..]
I want to make sure that if the selected Item has the quantity of 5, and you pass 6 or more to the sold_quantity, throw a validation error saying "You have only X in stock and wanted to sell Y".
I tried to override the save method, but however I try to do so, it changes nothing. When I try to access self.sold_item, it returns the name of the selected item.
When I try to do item.objects.get(name=self.sold_item), whatever I do it returns just the name of the item and I can't access other fields (known as Quantity).
Conc:
Item.objects.get(name=self.sold_item) returns the name of the item.
using the same but Filter instead of Get returns a queryset, which contains <Item: the items name> and I can't access other fields of it.
Per a comment on the question, this is the answer
have you tried this self.sold_item.quantity ? you can just check if self.sold_item.quantity < self.sold_quantity: raise ....

exclude a query result in another query

Here i want to do is that ,i want to list all the person who didn't blocked me.Here in the table Blocked there is two columns name
who and whose . In whose column i store the id of the person whom i blocked and in the who column i store my id. Now i want to do that, when the blocked person click on
view-person button in my web page he cannot see profile of the person one who blocked him.
when i did this query blocked_list = Blocked.objects.filter(whose = user_id). Now i got the list of the persons who blocked me. Now i want to exclude all this person from this query total_profiles = persons.objects.all().exclude(blocked_list). How can i do this.
models.py
class persons(models.Model):
full_name = models.CharField(max_length=200)
class blocked(models.Model):
who = models.ForeignKey(persons)
whose = models.IntegerField(null=True)
views.py
def blocked(request):
blocked_list = Blocked.objects.filter(whose = user_id)
total_profiles = persons.objects.all().exclude(blocked_list)
return render_to_response('profiles/view_all.html', {'total_profiles':total_profiles,'}, context_instance=RequestContext(request),)
please correct the question if it is not correct.
You can try this:
total_profiles = persons.objects.all().exclude(id__in = blocked_list.values_list('id', flat=True))
It's untested, but adapted from this answer.
Some notes:
if persons has the default manager, you can omit all().
whose does not have an index, so it will become slow when your dataset gets big. You can use a ForeignKey field instead of an IntegerField
the common convention is to capitalize class names and to write model names in singular i.e. Person instead of persons

populating prefixed fields - bug or feature?

Having the following models:
#models.py
Column(models.Model):
name = models.CharField()
Input(models.Model):
column = ForeignKey(Column)
text = models.CharField()
And the following form:
class InputForm(Modelform):
class Meta():
model=Input
The following works:
c = Column.objects.get(...)
i=InputForm({'column':c.id})
i.is_valid() #true
In my application I am generating many forms, to avoid clashes I prefix it:
i=InputForm({'column':c.id}, prefix=prfx()) #prfx() is dynamically generated
i.errors # ({'column':['This field is required']})
i.data['column'] is still the right value
I also tried:
i.column = c
i.errors # ({'column':['This field is required']})
How do I populate the column field?
I cannot save the form as long as it does not validate
EDIT What I am trying to achieve:
I am building dynamic forms:
form_list = [InputForm(column, prefix=column.id) for column in col_list]
In the template I iterate over this form list (and I want to set the column field to be invisible.
{% for form in form_list %}
{{form.as_ul}}
{%endfor%}
This form then shall be processed by an AjaxView. The relation between text and column is achieved by the invisible field.
The first parameter to the form is the input data, which is usually request.POST. If you render a Form with a prefix, you will see that all form html elements will have a prefixed name, for example <input name='yourprefix_text' /> etc. If you POST such a form to your Django app, the POSTed data will have the prefix, too.
So, if you are using a prefix, the input data needs to be prefixed, too:
f = InputForm({'yourprefix_column': c.id}, prefix='yourprefix')
Usually, it is a better idea to use the initial parameter to the form for default values, because otherwise the form is always bound, and this has some consequences, for example default/initial values for other fields are will not work.
f = InputForm(prefix='yourprefix', initial={'column': c})
# or ...
form_list = [InputForm(prefix=column.id, initial={'column': column})
for column in col_list]
If you want to always set the column to a programatically determined value, and not allow the user to change it, it is better to not include the field in your form, and set the field manually after saving the object:
f = InputForm(request.POST)
if f.is_valid():
instance = f.save(commit=False)
instance.column = c
instance.save()
To make your field hidden, you can change the widget, as described in the documentation:
class InputForm(ModelForm):
class Meta:
widgets = {
'column': forms.HiddenInput,
}
# ...

Filter using a CheckboxSelectMultiple returned from a form in django

I have a a form which contains a field :
item = forms.MultipleChoiceField( widget = forms.CheckboxSelectMultiple, choices=ITEM_CHOICES)
on the POST operation in my view, when I get the form back. I thought that the form.data['item'] should contains a dict, but it doesnt. it holds only the higher item_value.
how can I get the multi selection from the POST operation then ?
on my views.py
search_items_form = SearchItemsForm( data = request.POST )
if not search_items_form.is_valid():
...error...
if 'item' in search_items_form.data:
item = search_items_form.data['item']
here item equal only to one value while you can see in the field form it is set as multiplechoicefield.
also, when looking at firebugs I see over the parameter is the POST operation :
item 1
item 2
item 3
item 4
so the POST does contains multiple item X.
You should be accessing cleaned_data['item'], not data['item'].

Django select choices with optgroup fails to validate

I have a a form in Django with two inline forms. One of them is giving me grief.
My model is like so.
class BookingActivity(models.Model):
booking = models.ForeignKey('Booking')
program = models.ForeignKey(Program)
activity = models.ForeignKey(Activity, choices=programs_as_optgroups())
the activity ForeignKey choices are generated via this method:
def programs_as_optgroups():
activities = []
programs = []
for program in Program.objects.all():
new_program = []
new_activities = []
for activity in Activity.objects.filter(program=program):
new_activities.append([activity.id, activity.name])
new_program = [program.name, new_activities]
activities.append(new_program)
return activities
I'm trying to add <optgroup> tags to my ForeignKey select which is working. But when I submit the form I get an error: Cannot assign "u'3'": "BookingActivity.activity" must be a "Activity" instance.
This makes some sense - sort of. But if I check the request data sent from the form post. With choices either setup or not I get the same values, i.e.
activity = models.ForeignKey(Activity, choices=programs_as_optgroups())
and
activity = models.ForeignKey(Activity)
both return the a u'3' from the form. But I can't figure out why I get an error only when I'm using the optgroups.
I'm guessing you're trying
http://dealingit.wordpress.com/2009/10/26/django-tip-showing-optgroup-in-a-modelform/
in the blog
sub_categories.append([sub_category.id, sub_category.name])
you have
new_activities.append([activity.id, activity])
I think you're assuming you will get an object when it actually is a string you're getting back.