I'm new to Django, and I haven't found the answer yet in the extensive documentation. I'm asking for pointers to research, not for working code. That being said, here's my problem:
In one of my models theres a BooleanField (it gets rendered in the admin form as a checkBox). Let's call it 'A'. It only makes sense to edit other field (say, CharField 'B') if A is checked.
So, is there a way to make B read only, or even changing its content to an empty string, dinamically, if A is checked? Thank you.
(Django 1.5.2, Python 2.7.5)
You're going to need several things to make this work. You may be able to skip some of them depending if you mainly care abut the UI, or the data integrity in the db.
Since the user can (presumably) check/uncheck Field A on the client-side you need some Javascript to enable/disable the appearance of Field B. These docs show how to load custom JS in your ModelAdmin class:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-asset-definitions
In your ModelForm you may want to do some check in the __init__ method against the value of self.instance.field_a and substitute some kind of ReadOnlyWidget for Field B for the initial display of the form. These docs show how to give your ModelAdmin a custom form class:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form
If you are writing some Javascript to do that dynamically it make be easier to skip this step and just do it client-side.
Finally you can use Django model validation to ensure that Field B is saved with a null value if Field A is checked:
https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects
Related
I have a database with a model that I'm updating by adding a new field. When I added the field, all the old objects in the database populated that field with an empty string value. I need these fields to have values.
In the future, objects be forced to contain a value by either specification or a default value.
What is the best way to update this field for the old objects?
I have a couple ideas but I'm not sure if one is 'proper.' Again, this is something that only needs to be done once, as all future objects will have all required data.
Enable PUT by adding the UpdateModelMixin to the ViewSet, update the fields, then disable PUT (I do not want PUT permanently allowed)
Create some sort of migration script to do the updates for me.
Something I'm missing?
I may be misunderstanding the question, but when you create a new field you can specify the default value you want to populate into the existing database so you can give it any value:
https://docs.djangoproject.com/en/2.2/ref/models/fields/#default
If you can't roll back and re-create the field, I would use the Django shell to do it since this is a one-time change, something similar to:
ModelName.objects.update(field='newvalue')
That way you don't need to change your configuration or your code or anything.
I have a project in which I need to add a custom form field to a form (or formset) in which depending on the choice in the custom field selected, an integer in a database field is changed.
I can't seem to find any examples or prior questions which imply how to modify a database field via a custom field. I suspect it is done by overwriting the save() function in a ModelForm but cannot work out how.
Any advice on solving this problem would be greatly appreciated.
An Example:
My class has an integer field which is the field that needs updating.
class Employee(Model):
years = models.IntegerField()
However this field cannot be updated as it is, instead what is needed is a ChoiceField (I think) with different options that, depending on the selection, changes the field with a +1, -1, or reset to zero.
As previously mentioned this is where I imagine some work with the save() function needs to be done but am unsure.
As a side note in case this affects what can be done, eventually this ModelForm will need to be used in a formset so I can edit multiple objects on one page.
First of all I have tried to research my problem but have not been able to find what I need. My problem might be related to the design of my project (any help would be appreciated).
The problem I am facing is as follows:
I have a few models
I have a model that would be used specifically to create a ModelForm
In this model I have ForeignKey field that is represented by default as a select/option input widget in the ModelForm (for each the value attribute is the ForeignKey and text between the tags is the __str__() of the model the ForeignKey points to. The user sees the __str__() and value attribute of the option tag is submitted which is great).
So far so good but I want to replace the widget with an input text field so I can implement it as a search field.
Now when the user submits the form the string entered in the text input field is submitted and of course django doesn't like that since it expects a foreign key
I already can think of a few solutions to the problem and I am sure I can make it work but each of them feels like I would be violating some best practices. So my question is what should I do?
Do I exclude this particular field from the ModelForm and implement it as an input text field then after form submission make a query with it's value and then store the ForeignKey to the DB
Do I manipulate the data with JavaScript upon submission so that Django receives correct information
Can I clean this fields data with Django and transform it from string to FK?
Am I going the wrong way with this or there is a Django feature for this type of situation?
If anyone has the same problem here is the solution (to my problem at least):
I tried to use the clean_<fieldname> method to change the user entered string to database id. The method wasn't executing because the validation process was stopping earlier because of the difference between the form field and the widget. I redefined the form field to CharField so that step of the validation was working and then the clean_<fieldname> method executes without a problem.
This was my original question, but it was not answered and so I thought Id post again with some of the strategies that I have tried, and be a little more specific.
I want to create a dynamic admin site, that based on if the field is blank or not will show that field. So I have a model that has a set number of fields, but for each individual entry will not contain all of the fields in my model and I want to exclude based on if that field is blank. My project is about bridges, and so to put it in practical terms I have a model that has every bridge part in it (this roughly is equivalent to 100), but each individual bridge (mapped to each unique brkey) will not have all 100 bridge parts. And so, I can prepopulate all of the fields it does have, but then the admin site has 100 other fields, and I would like to not display those fields that were not used on my admin site for that specific bridge, but those fields will differ with pretty much every bridge.
Like I said before, I have a unique bridge identifier(a unique 15 digit string), that correlates to each bridge, and then all of the various different variables that describe the bridge.
I have it set up now that the user will go to a url with the unique bridgekey and then this will create an entry of that bridge. So (as i am testing on my local machine) it would be like localhost/home/brkey and that code in my views.py that corresponds to that url is
Is this a final route that I have to take? I am very new to JavaScript and so I do not want to take this route but I will if I have to. Also does Django use Javascript in anyway that is syntactically different? If so I cannot find any Django documentation on incorporating Javascript into my admin site.
A final option that I have exhausted is to use global variables. Instead of having the url that creates the entry in my Views.py, I placed it in my admins.py, and had my modelAdmin class in there as well, so like this.
admins.py
-set up global variable
bridgekey_unique = " "
If I can find a way to either pass that unique bridge key to my modelAdmin class, or figure out if that said field is blank because the bridge doesnt have that part, I will be able to achieve what I want without using Javascript. I have tried a lot of variations of all two of theses strategies to no avail, but have not tried the JavaScript idea as I dont really know any javascript at all.
Sorry for the lengthy post, but people said I wasnt specific enough. Any help would be greatly appreciated.
I didn't read all of that - sorry, there's too much. But I did notice your comment that you expect to access in your modeladmin definition a variable that you set in your view. That can't possibly work.
Anything at class level is always executed when the module containing the class is first imported. That is when the server process starts up, so there is no possible way anything done in the view can have happened yet.
You almost never want to have any logic at class level. You need to put it in methods, which are called at the relevant time. In this case, you probably need to use the get_fields method.
Edit
Looking further up at your attempt at a get_fields method, I can't see at all what you are trying to do here. 'prestressed_concrete_deck' is a literal string, and could never be None, so neither of your conditions can ever be true. And as to your question about what the parameters are, the documentation for that method explains clearly that obj is the object being edited.
This is really frustrating,
I can't and can't find how to create a form (I'm guessing a forms.Form form) to update just one field of a more complex model.
The model has 5 fields, and a form to create, update all of them.
But in a different case i need to let the user update only the title (a field in the model), so i need tried so many things until now (including creating an HTML form by hand and from the view to save it, creating a forms.Form and many more, nothing seem to work), There is no code here because i don't even know which one to put....
Maybe some one can help me with that, I'm sure it is a simple thing, But for some reason i am stuck on this for a long time...
Thank you,
Erez
If you're using ModelForms, you just have to define a fields attribute in Meta as a tuple containing just the names of the fields you want. See the documentation.