Dynamic model fields in Django - django

I have a model, for example: "food". Each one of this has some basic info: "name" "calories", etc. I would like to provide a form where the user can add extra fields. For example, if the user is adding a new "food", beside the basic info he could also add new fields, like "sugar", "vitamins", etc.
How could I add the fields to the database so that it can be retrieved/queried later?
Thanks!

Jacob Kaplan-Moss has an extensive writeup on dynamic form fields:
http://jacobian.org/writing/dynamic-form-generation/
Essentially, you add more items to the form's fields member variable
during instantiation.
Source
Even better.

Related

Allow additional attributes, like placeholder text or icon, on model

I use modelforms in several places in my app, and have written custom bootstrap form rendering. It's working well, but I'd like to be able to add addon_before to some of my fields (example, for twitter_username i'd set addon_before='https://twitter.com/. I'd also like to specify icon classes and placeholder text for some fields.
I know I can do this in the form rendering, but I render the same fields in several different forms, and I dont want to repeat the form settings. using the twitter_username example, is there a way to globally set wherever that field is used in a modelform, to include a set of attributes and values
{'addon_before': 'https://twitter.com/', 'placeholder': '#username', 'icon': 'fa-twitter'}
Would love any suggestions!

Save the dynamically populated value on dropdown

I'm using wagtail CMS for Django, I want to add a dynamically populated value for a dropdown and save it on the Page model, this is my code:
class MyPage(Page):
domain = CharField(max_length=10, choices=MY_CHOICES)
subdomain = CharField(max_length=10, choices=[('', '------')]
I've got some frontend logic to populate dynamically the options for subdomain, but after I hit save I got: The page could not be created due to validation errors And in the subdomain field: Select a valid choice. [my value] is not one of the available choices.
I can't use ForeignKey to populate subdomain because it depends from an external API service that we're using.
I tried to use a custom field that inherits from CharField with no success, it looks it executes validate method only for the domain field.
If you use the choices argument, you have to predefine the list of possible values. Read the relevant part of the docs (last two paragraphs of that section).
You could omit the choices argument from the model field definition and only render a HTML select tag in the frontend (which is then filled with options dynamically, like you explained).
You could also look into changing the default widget of the CharField to a select tag, like this answer and this part of the docs show.

In Django, how to validate a (multiple) cholice field when the choices are added by Javascript?

I have a ChoiceField where the choices are not known at the time the HTML is rendered; they are defined dynamically by the user and added to the form through Javascript, but the validation naturally fails since the selected option is not in the choices attribute (which is just an empty list). I have tried setting the field to a CharField, but then the validator just gets a string value that needs to be converted into a list before it van be used. Ah, and I'd like to avoid subclassing the field class as it's just for one occasion.
I hope this is clear. Any ideas?
Don't subclass the field class but override the clean_<yourfield> method in your Form class. See the docs here.

Customising specific fields in Django Admin change form

I have a couple of fields in my model that to which I wish to add a link that will allow the user to search for names/files (external from the application's database).
So what I would like is:
Field name: [text box] - LINK
Is there a straightforward django way of achieving this?
Cheers.
You need to change the widget that the form field uses to display the models information. You basically add some html after the input to link to where you want.
Here's some code I put together to create a widget that displays how many characters are left for a CharacterField so it's similar to what you are looking to do:
https://github.com/pastylegs/django-widget-charsleft/blob/master/widget_charsleft/widgets.py

How to display more things in admin.StackedInline

I have Article model and a Comment model. Comment is created in admin.py as admin.StackedInline, and it has several fields, notably content and lastUpdate. For lastUpdate, i have specified as follows: lastUpdate = models.DateTimeField('last update', auto_now=True). Understandably, lastUpdate is not displayed when i try to add new comment (or edit old ones). However, i would like it to display for older comments if possible, as a read only thing. Is there anyway of accomplishing that?
Thanks a lot!
Jason
I guess if this http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields doesn't do what you want it to do, have a look at this: In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?