set every single form readonly without using widgets in the model - django-forms

I am trying to build a template with some forms. I have a model with about 400 attributes for one entity. Now i want to make two different templates. In one Template the attributes should be listed like django form do. In the other template the attributes should be set readonly.
I don't want to create two diffent Forms for every attribute by using widgets.
cust_form = GeneralDataForm(instance=_customer, auto_id=False, label_suffix='')
I tried inserting the widget here but it doesn't work.

using this code you can make any form readonly. are you looking for something like this?
cust_form_read_only = make_form_readonly(cust_form)
def make_form_readonly(form):
for name, field in form.fields.items():
field.widget.attrs['readonly'] = True
field.widget.attrs['disabled'] = True
return form

Related

How to make a CreateOnly view in Django-Rest-Framework?

How can I create a "Create Only" view? I just want to allow the user to create an Object and nothing else.
My current code looks like that:
views.py
class BookingRequestCreateViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
serializer_class = BookingRequestSerializer
def get_queryset(self):
return None
This works fine. But I have in my Model a ForeignKey and in the web view every user can see all id's. (Select input for the ForeignKey in the REST web interface)
How can I stop this behavior?
Thank you
By default, a related field (PrimaryKeyRelatedField, SlugRelatedField, etc.) is rendered with a default HTML select. Check this snippet.
Django REST framework allows you to change the rendering style of a serializer field by using the style keyword argument (check this doc).
If you do not want the API to display the IDs of existing objects within a select, change the style argument of your serializer field, setting your rendering style to a simple HTML input. Something like this:
class BookingRequestSerializer(serializers.ModelSerializer):
...
related_field = PrimaryKeyRelatedField(
queryset=RelatedModel.objects.all(),
style={'base_template': 'input.html'},
)

Django how to create a post request for multiple forms.?

i have multiple forms in the same template, each form is linked to a button(aform button , bform button.....)when clicked gets a pop up form with some fileds, how can i save that form by creating a post request in views.py
(i know to create a POST request for a single form.) but how do i achieve that for multiple forms.
NOTE: only one form can be submitted at a time.
def example_view(request):
context = {
'aform':AForm(),
'bform':BForm(),
'cform':CForm(),
'dform':DForm()
}
template = "xyz.html"
return render(request, template, context)
how do i create a post request for multiple forms?
You can do this in following ways.
Submit your form with ajax and handle each form separately. In this way, every form will be posted in different links.
Put different URLs in the action for the two forms. Then you'll have
two different view functions to deal with the two different forms.
Read the submit button values from the POST data. You will have to send a parameter with which you can tell which
submit button was clicked.
forma = FormA(prefix="a")
formb = FormB(prefix="b")
which_form = request.GET.get('form_name')
if request.POST:
if which_form == 'a':
forma = FormA(request.POST, prefix="a")
if forma.is_valid():
obja = forma.save()
if which_form == 'b':
formB = FormB(request.POST, prefix="b")
if formb.is_valid():
objb = formb.save()
I've recently been fighting with a similar situation. I have a 'master' form which contains 3 'subsections' or 'subforms'. I thought of them as 4 forms for way too long. After searching a dozen SO posts.
I arrived at the following:
In the html, use ONE tag, which will POST to your view. You can use s or Bootstrap classes or whatever to make the HTML look like separate forms, but I only have/need one submit button. In your example, place {{aform}}, {{bform}}, {{cform}} and {{dform}} inside the single tag pair.
In the view, while building aform, etc, assign a prefix to each form class (https://docs.djangoproject.com/en/4.1/ref/forms/api/#prefixes-for-forms). In fact, that same point in the documentation says outright "You can put several Django forms inside one tag. To give each Form its own namespace, use the prefix keyword argument:"
In the POST processor of your view, use the same prefixes. This lets you resplit the combined POST data to aform, bform, cform and dform.

How to format the values of a model in Marionette Backbone View before rendering?

If you implement the onBeforeRender method the is no way to access the model values in order to format them temporarily
Ideally you would want to format the values just before rendering without changing the model values of course!
How to do it?
By checking this link: http://derickbailey.github.io/backbone.marionette/docs/backbone.marionette.html
You will find that serializeData is being used just before rendering the template
So by overriding it, like below you can format the object values any way you want before rendering
serializeData():any {
var obj = super.serializeData();
obj.totalEnergy = Math.round(obj.totalEnergy).toFixed(0)
return obj
}
Marionette Views also have templateHelpers for this purpose. templateHelpers can be used to provide any additional data to the view apart from model. Functions can be specified to format model's data to be rendered on the view. Check out the basic example for template helpers in Marionette view's docs - http://marionettejs.com/docs/marionette.view.html#basic-example

Adding validation property attributes in views with Html.EditorFor() methods not inside a Html.BegingForm() method

I have noticed that validation attributes are only added to the elements that were created via Html.EditorFor() helper method and which are inside a Html.BegingForm() method, that respectively creates the "Form" tag and attributes.
Is there any way, besides manually creating the elements and attributes of course to add the required validation attributes to elements created with helper methods and which are not inside the Html.BegingForm() method ?
I need to validate at the client side and don't want to manually either create said attributes or script this behavior explicitly and instead take advantage of the MVC feature that adds said attributes automatically as per metadata on the model for use with the jquery-validate plugin at the client-side.
The unobtrusive validation attributes emitted only if:
the UnobtrusiveJavaScriptEnabled flag is set to true
the ViewContext.FormContext is not null (e.g the Html helper is executed inside a Html.BeginForm block)
So you can manually create a FormContext and assign it to ViewContext.FormContext before using your Html helpers:
#{
ViewContext.FormContext = new FormContext();
}
#Html.TextBoxFor(x => x.SomeProperty)
However you should note that with this approach you lose the from nesting feature of Html.BeginForm so if you want to create a new logical form you need to again create new FormContext() and manage the old context yourself.

Is it possible to use a custom html helper editor template without tying it to the model?

So normally I am doing something like this:
#Html.EditorFor(m => m.MyDateTime)
Then I have a custom template DateTime.cshtml that is used as the editor.
Whatever the date value of Model.MyDateTime is will be displayed as expected, and as expected the name of the field on the next POST will be MyDateTime.
My desire is to use the custom template in the Html.EditorFor WITHOUT binding in the model object, instead I wish to give it a form field name to be POSTed but have it start out blank.
However I can't find an override of Html.EditorFor() that will allow me to not specify a model object, so I can only specify the template to use and the html form field name so it starts empty.
Note: I tried #Html.EditorForModel("DateTime", "MyDateTime") but just got an error so I think that I misunderstood what that is for.
(I know I could just have MyDateTime be null coming back from the controller but that is not what I am asking here.)
Why would you want to use an EditFor that is going to edit nothing (no model passed)? Instead of going down that road, you should probably look at using a View or PartialView which do not require having a Strongly-Typed model.

Resources