It's a bit odd but I would like to define some properties of a form field like its widget or class from the model definition. I know it is easy from the form but I'd like to know if it's possible from the model. I'm not sure but I think I remember having seen something like that some day.
Well, you can create your own subclasses of model fields and redefine their formfield method to add the properties you want but it might not be worth the effors as you'll be overriding . That's hour call, however.
Anyway, in case you decide to try this, make sure to follow these two sections from the documentation:
ModelForms and custom fields
and
Specifying the form field for a model field as the default implementation of Field.formfield does some important stuff you generally don't want to omit.
Related
I have a ManyToMany relationship between two Django Models: Team and Member. A single Member can be part of multiple teams. I am able to successfully bind a Form class to a CreateView, and, using the standard ModelMultipleChoiceField,can successfully save the Form using the save_m2m method.
However, the default widget for the field is not suitable for my user experience. Instead of using a picklist, I would like to create a separate select box for each number of selectable Members per team. For example, if the Team can have 7 Members, I would like to show 7 select boxes, rather than one pick list that a user selects 7 different objects from.
I understand I may not get a complete answer, but would appreciate any pointers on if I should be looking into overriding the Field with a custom MultiWidget, or if using an inline formset might be a more appropriate route. Or, something else...
At the end of the day, I ultimately decided to stick with a single ModelForm for the Create Team form. Within this ModelForm, I dynamically create the number of fields I will need for the number of Member per team, and have created a function within the form that yields those fields.
I perform validation on those fields within the generic clean method of the ModelForm. I use the yield method within the Template to control displaying the individual fields.
I am sure it is not the most Django-y approach, as many people seem to use inlineformsets in theory, but this worked and the code does not seem overly hacky or unmaintainable.
I'm working on a project that involves a form with some standard fields and some custom field users define later. The standard forms are defined on a model in models.py. For example:
class Order(models.model):
number = models.TextField()
date = models.DateField()
I then use this model to create a simple model form to make a way to fill in the information. That's pretty standard Django.
The tricky thing is that my users want to be able to add arbitrary fields to the form. They would like to be able to use the Admin interface to basically modify the form and add values to it at run time.
So, they might want a new text field called "Tracking Number" or something like that. The trick is that they only need it sometimes and they want to be able to add it dynamically without rebuilding the whole database.
I can create a fairly simple model to represent the custom fields like so:
class CustomField(models.Model):
type = models.CharField(choices=FIELD_TYPES)
required = models.BooleanField()
I think I can then take the ModelForm for the Order class and extend it to add these custom fields. What I am unsure of is how to link the custom field values back to the Order.
I know this all might sound odd, but in practice it makes sense. Each user has slightly different needs for the form and want to tweak it. If I have to hard code the models to have their specific fields, then I will have to have a fork for each user. That simply doesn't scale. If instead they can simply add the fields through the admin interface, then things are much simpler.
I feel like this is something that is perhaps already solved by someone out there. I simply cannot find a solution. I can't be the only one who has gotten this kind of request right?
I guess this is a simple question, but I am not being able to find a definitive answer whether this is possible or not.
I have a Model object that is being passed to my template during rendering. While I use most of the Model fields to show their values, I came across a need to show a few of them as formfields (with their respective HTML element like rendered via ModelForms). Can ModelForm class usage be avoided here and simply use the Model's field to be rendered as formfield directly from template?
an example:
class MyModel(models.Model):
month = models.PositiveIntegerField(_('Month'), choices=MONTH_CHOICES)
year = models.PositiveIntegerField(_('Year'))
Now in template based on the above Model example I want to show the year as a value but month as a dropdown with selected current value?
Any pointer appreciated!
Use case:
Imagine a generic list_view like case where you are rendering a queryset. What you have there is object per iteration, however on the list view you want to allow your users to perform some quick editing of few object attributes to avoid forcing them to go to full edit mode (maybe via simple ajax).
No.
As canvassed in the comments, this is not possible. A model, and its fields do not know about forms - that is what forms, and modelforms are for.
The right way to do this is to wrap your model objects with a modelform, which you can adjust (using inheritance) to do whatever you want with the non-form fields, if you wish to make this more transparent.
Creating modelforms in the template means that you have nowhere to process the forms in django. Apparently you want to interface them with some kind of ajax interface, so perhaps this is not a problem for you, but in any case, I fail to see how it would be easier than simply creating the modelforms in the view.
I've managed to get Django Forms to dynamically generate additional fields based on the relationship between a specific instance (eg. 'product type') and another model (eg. 'product attributes') eg. products have common attributes like weight and price but a book has a page count and a computer has specs.
I'd like to be able to do the same with ModelForms so that I can just call form.save() but I'm not sure what the right approach would be to do this or where to start. At first I thought it would be possible by overriding some of the methods but then I've looked around the models.py file and it seems that I'd need to add quite a bit of code at various places in there to handle the additional fields ie. quite a lot of work. Or am I missing the easy way?
Without knowing the specifics, I'd say you're right. If the additional fields are not part of the model, then at the least, you'd have to override the ModelForm's save() method.
How can I use boolean choices in a model field to enable/disable other fields. If a boolean value is true/false I want it to enable/disable other model fields. Is there a way to natively express these relationships using django models/forms/widgets? I keep writing custom templates to model these relationships, but can't figure out a good way to represent them in django without a special template.
For example:
class PointInTime(models.Model):
is_absolute_time = models.BooleanField()
absolute_time = models.DateTimeField()
is_relative_time = models.BooleanField()
days_before = models.IntegerField()
So if the is_absolute_time is True, I want the absolute_time entry to be editable in the GUI and the days_before entry to be grayed out and not-editable. If the 'is_relative_time' flag is True, I want the absolute_time entry to be grayed out, and the days_before value to be editable. So is_absolute_time and is_relative_time would be radio buttons in the same Group in the GUI and their two corresponding fields would only be editable when their radio button is selected. This is easy to do in a customized template, but is there a way to use a model/form in django to natively show this relationship?
It would be helpful to clarify what you mean by "natively show this relationship," and think clearly about separation of concerns.
If all you want is to "gray out" or disable a certain field based on the value of another field, this is purely a presentation/UI issue, so the template (and/or Javascript) is the appropriate place to handle it.
If you want to validate that the submitted data is internally consistent (i.e. absolute_time is filled in if is_absolute_time is True, etc), that's a form-validation issue. The place for that logic is in the clean() method of your Form or ModelForm object.
If you want to ensure that no PointInTime model can ever be saved to the database without being internally consistent, that's a data-layer concern. The place for that is in a custom save() method on your model object (Django 1.2 will include a more extensive model validation system).
All of those options involve writing imperative code to do what you need with these specific fields. It may be that you're looking for a way to represent the situation declaratively in your model so that the code in all three of the above cases can be written generically instead of specifically. There's no built-in Django way to do this, but you could certainly do something like:
class PointInTime(models.Model):
field_dependencies = {'is_absolute_time': 'absolute_time',
'is_relative_time': 'days_before'}
... fields here ...
Then your model save() code (or your Form clean() code, or your template), could use this dictionary to determine which fields should be enabled/disabled depending on the value of which other one. This generalization is hardly worth the effort, though, unless you anticipate needing to do this same thing in a number of different models.
Lastly, a few schema design alternatives you may want to consider to get your data layer better normalized:
If there are only two valid states (absolute and relative), use a single boolean field instead of two. Then you avoid possible inconsistencies (what does it mean if both booleans are False? Or True?)
Or simplify further by eliminating the booleans entirely and just using Null values in one or the other of absolute_time/days_before.
If there might be more than two valid states, use a single IntegerField or CharField with choices instead of using two boolean fields. Same reason as above, but can accomodate more than two options.
Since a RelativeTime and an AbsoluteTime don't appear to share any data fields with each other, consider splitting them out into separate models entirely. If you have other models that need a ForeignKey to either one or the other, you could model that with inheritance (both RelativeTime and AbsoluteTime inherit from PointInTime, other models have ForeignKeys to PointInTime).
I'm not entirely sure what you're doing with these objects but whichever the user chooses, you're pointing to a single moment in time. "5 days ago" is "Thursday" and vice-versa.
So unless the dates roll with the site (eg the record with "5 days ago" will still mean Thursday, tomorrow, etc), surely this is only an interface problem? If that's the case, I'd stick with a single value for the date in your Model and let the form and view do all the work.
That solves the auto-generated Admin side of things as you'll just have one field to contend with but it won't natively give you the choice between the two unless you write your own form widget and override the ModelAdmin class for your Model.
If this isn't the case, please ignore this answer.