Django forms.Choicefield get selected Choice - python

I need to get the selected Value of a forms.Choicefield for an if/else statement which produces another forms.Choicefield based on the selected Value
forms.py:
class ReceiverForm(forms.Form):
receivers = forms.ChoiceField(choices=db_mails(), required=True, label='Receivers')
if db_certs(<- selected value from receivers ChoiceField ->):
print "cert found"
encryption = forms.ChoiceField(choices=EncryptionChoiceAll, initial='smime_mail', required=True, label='Encryption')
else:
print "no cert found"
encryption = forms.ChoiceField(choices=EncryptionChoiceNoCert, initial='smime_mail', required=True, label='Encryption')
db_mails() and db_certs(mail) are working as expected
Is there a way to achieve what i need in forms.py or am I totally wrong with the design?

When the form is built and you specify the choice list, you have no way to know which value is selected, as:
You create an instance of the form class
This instance is used to create the view (On a GET request). The user can modify the selection
He submits the form. For this you create an instance of the class, which is filled with the POST values.
So at the time you create the class you do not have the information.
There are possibilities to have dynamic values in one choice, depending on the other one, but this needs to be done on the client side, when the user changes the selection:
Use javascript/jquery to update the list of choices depending on the answer. For this, you could have hidden values in the HTML file, and Javascript will update the list from these hidden values.
If the choice to update is more dynamic (For example a list of towns depending on the post code), you still need to use Javascript, but with Ajax that will send an asynchronous request to the server to get the list and update the choices.
There are plenty of tutorials to do this, and this is not directly linked to Django. As an example:
https://css-tricks.com/dynamic-dropdowns/

Related

MultipleChoiceField with massive choices best practice

I need have MultipleChoiceField field in a form that should have over 50000 choices, therefore I cannot render it properly; I emptied the choices and went through an Ajax call to filter the options depending on the user inputs. Problem is that Django is obviously complaining that the choice is not part of the empty choices I provided.
I think of three solutions to fix this but would like to know which one is 'best practice' or if there was a better one :
Create a second form which I check when the request is POST, same as the first one but with the choices initialized at the server starts
Define the __init__ of the form where if passed a parameter it would set choices to a variable initialized outside the form at the server starts
Find a way to display the input without displaying the options in the template
I went through the second option:
in the class object the queryset / choices is set to the full list
in the init it is set to empty
This show nothing in the template (and I add through Ajax) but allow everything in the cleaning

Connecting django multiple choice field with textinputs

In django models, I used models.MultipleChoiceField but i want that those variables in the set of choices to be linked to a textinput which will be saved into the django admin. So the user selects the choice then keys in a textbox and saves for that choice is that possible to implement?
I think you can follow this link
If you want to "those variables in the set of choices to be linked to a textinput", it will be use forms.ChoiceField in forms.Form.
it will be nicely if you posting your code, the better we may know what you want.

Eve framework: user restricted resource access

I'm using Eve framework and I'm trying to use User-Restricted resource access as described in:
http://python-eve.org/authentication.html#user-restricted-resource-access
I'm doing something like:
class CustomAuth(TokenAuth):
def check_auth(self, token, allowed_roles, resource, method):
# Get user as an instance of UserResource.
if user and hasattr(user, 'id'):
self.set_request_auth_value(user['id'])
request.authenticated_user = user
...
So, there are a few question from my side:
Is it enough for using User-Restricted Resource Access?
How this field adds into user created objects?
Is this additional field called id in my user created objects? Is it possible to rename it?
As I understand it should be named same as it's called in User resource. Is it true?
Does this field (property) applies for newly created objects only? Is it possible to fetch previously created objects by current user following this way?
Well, I want to know an answers for my questions + clarify how it may be used.
Is it an expected way to extract it somehow in my hooks?
user_id = current_app.auth.get_request_auth_value()
current_app.data.driver.session.query(resource).find({'id': user_id})
Is this block of code from hook expected?
How it behaves if my requested resource has its own id field?
P.S. I was reading a post:
https://stackoverflow.com/a/35654252/7335432
The user-restricted access feature prevents users from accessing records they didn't create. The set_request_auth_value() method does:
1) Upon making a POST request to create a record, it automatically adds a field specified as AUTH_FIELD (or auth_field if you only want to do it to a specific resource). So for example, if you declare in settings.py
AUTH_FIELD = "my_auth_field"
and then add
set_request_auth_value(user['id'])
to your authentication method, that means that your app creates a field "my_auth_field" that has its value set to whatever user["id"] is. So if you were to go into Mongo Compass or some other DBMS and manually inspect your records, you'd see a "my_auth_field" field in there.
2) On GET requests when you access those records, Eve checks the "my_auth_field" value against whatever user["id"] is, and only displays the records where "my_auth_field" is equal to user["id"]. Since this field is added automatically when you create a record using Eve, it effectively filters out everything that specific user didn't create.
So yes, it only applies to newly created objects. I'm not sure exactly what you mean by "is it enough", but it doesn't look like 'user' is declared anywhere in your authentication class. You might wanna check out this tutorial they do incorporating user restricted access into token authentication.

Update Multiple Items with Input Value in Django Admin

I would like to set the value of a field in multiple rows of Django Admin.
For example if I had database of books with shelf locations I might move several books to another shelf. I need a way, within Django Admin, to input the new shelf location and update the multiple selected items.
I have seen that you can run Admin Actions but I need an easy way to input a value into the action.
You can do this with admin actions, by providing an intermediate page with a form to input the value you want:
https://docs.djangoproject.com/en/1.8/ref/contrib/admin/actions/#actions-that-provide-intermediate-pages
Alternatively you could use some client-side scripting to collect the value from the user and append it to the querystring (or as an extra input field int he POST data) when submitting the admin action form.
Your admin action function receives the request object as an argument so has access to the extra GET/POST fields:
https://docs.djangoproject.com/en/1.8/ref/contrib/admin/actions/#adding-actions-to-the-modeladmin

Django ModelForm, having a foreign key as a hidden field

I'm basically building a very trivial form. Let's stick to the books/publisher examples given in the django tutorials and build upon that.
I have a user login to the web app, at which point the first thing they can do is click on a publisher. This publisher then gets saved for their session. Upon that I take them to a create book form. In there I embed the the publisher's id from the database into a hidden field.
Upon the user submitting an HTTP POST, I do something like:
mybookform = BookForm(request.POST)
if mybookform.is_valid():
abook = mybookform.save(commit=False)
abook.publisher_id = request.POST['publisher_id']
mybookform.save()
Yes there's a few naive things done here, such as blindly grabbing the publisher_id and verifying if it's indeed a real publisher id, amongst other security issues. Let's just not pay attention to that for the moment.
My question is, is there a better way of handling this? Although hypothetically this example doesn't make logistical sense, in my particular app the example actually makes sense. The problem is I get a ValueError exception saying publisher_id needs to be a Publisher instance.
Now I can easily retrieve a publisher instance with Publisher.objects.filter(id=..) and use that instead. The question is, is it really necessary? Can I avoid the additional query to the database and somehow update this form instance in a more 'elegant' fashion?
Also, is it possible to somehow embed the publisher in a hidden field so that I do not need to do mybookform.save(commit=False) and just do mybookform = BookForm(request.POST) followed by mybookform.save() immediately?
Retrieving the instance of the publisher does protect against client-side changes that might reference a completely invalid publisher.
To your second question, yes you can include that field as a hidden field by overriding the field in the ModelForm with the approriate form field setting the widget to HiddenInput.
There is no better way to do this.
I would use the get_object_or_404 function for this.
And yes, you can prevent this to be modified by the user by setting the model field to editable=False,

Categories

Resources