I am beginning learning django and have just come across django forms (I've always used manual forms in the past in django templates).
Should I always use django forms no matter what or are there scenarios where I should write the forms in the templates manually?
You can use your own forms, but it is better to use django forms because it provides more customization and flexibility.
It is easy to change the type of "widget" rendered with very little code change when you use django forms.
For example:
class MyForm(forms.Form):
my_field = forms.ChoiceField(choices=CHOICES) #choices can be a tuple
Would render as a checkbox field.
If you want to render the same as a Radio button, all you would have to do is:
class MyForm(forms.Form):
my_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
You would have to manually change the entire code if you have your own form.
You can also do some custom field level validation on the server side in one pass (Example, check if username is unique) - You can achieve the same in a custom form, but you will have to handle every scenario yourself.
Also, django has ModelForms which would be a replica of the Model object - that tremendously reduces the amount of work that needs to be done for validation, and form processing.
Related
I need to override the way a Select2 widget of a particular ForeignKey is behaving in the Django (4.1) admin.
Namely, I am trying to increase the number of objects returned by the AJAX requests and defined by paginate_by in AutocompleteJsonView.
Sadly this great solution no longer works with Django 4.
How can I extend AutocompleteJsonView and somehow tell Django to use my custom view?
EDIT: my current workaround is to override get_paginator on the ModelAdmin by setting paginator.per_page to whatever value is suitable, but that doesn't answer to broader question of customising the autocomplete behaviour of Select2 widgets in the Django admin.
Let's say we have the following pseudo database structure:
models.py
class Order(models.Model):
...
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
...
So each Order may contain one or more OrderItems.
By default, if I render the default form for these models, we will end up with two separate forms, where the user will have to create the Order first in one form, and then navigate to another form for OrderItem to start creating OrderItems for that Order.
Unless I create my own custom form from scratch (which is not integrated with any models) and then write the code to connect it with data models in the server-side. However, this is a very common use case so there has to be a way to handle such a scenario without having to rebuild so much from scratch.
Django already has a ManyToManyField which allows us to handle a similar kind of operation where what the user sees in the auto-generated form is simple, yet it involves interaction with multiple data models. How come there's no way to handle such form representation of data without having to do so much from scratch?
For example, in Django Rest Framework we can use Nested Relationships to define one model serializer as a field of another model serializer. But for Django models, I couldn't find any documentation for anything similar.
I am trying to add a non-model form in django admin interface and am not able to find any particular way to do it. This form would do some processing and change some data in the DB. But this is not related to a particular Model and should stand out. This form should not be available for the user to use.
One thing I can do is add the form to the general view and prohibit using permissions but I was thinking since django admin interface already exists, it would be better to add that to the django admin interface.
Is this possible to do in Django?
You can add arbitrary views that within a ModelAdmin that do whatever you want. See the documentation for ModelAdmin.get_urls. You can do the same at a higher level by defining AdminSite.get_urls.
Setup:
Python 3.5.1 with Django 1.9.
I have a class-based generic view CreateRentView operating on the model Rent. I implemented a custom ModelForm RentForm to implement additional validations (e.g., ensure start_time <= end_time).
When creating a new Rent (via CreateRentView), first user defines start and end time. This triggers an AJAX request to get the available objects for this time frame and fills the rental_objects HTML widget using Javascript (see screenshot below).
Problem:
Everything is working fine (custom validation and AJAX communication), but when submitting the form I get a validation error for (many-to-many) field rental_objects: Select a valid choice. 1 is not one of the available choices.
Note: in the screenshot below, rental object MB1 was selected before submitting the form.
This is caused because I want to initialize the field rental_objects empty. Therefore, method get_form() of class CreateRentView sets form field rental_objects to an empty QuerySet:
def get_form(self):
form = super(generic.CreateView, self).get_form()
# Rental objects are retrieved via AJAX after start and end time is defined.
form.fields["rental_objects"].queryset = RentalObject.objects.none()
Obviously this triggers an internal Django validation that ensures that this field is submitted empty.
How can I avoid this validation?
PS: Of course, I could not override get_form() and empty the HTML widget for rental_objects using Javascript. But, this would be just a messy workaround
Django-AJAX-ManyToManyField:
I believe this is from your rental objects' choices.
If you use integers for your choices you should use IntegerField. For CharField use strings
I am using django 1.1. I need to override an admin model form so that I can log changes in a many-to-many field. How do I do this?
Form Code:
class ClientAdminForm(forms.ModelForm):
_filters = ClientFilter.objects.all()
filter = forms.ModelMultipleChoiceField(required=False, queryset=_filters, widget=FilterWidget(urlname='client', queryset=_filters, header='Filters added'))
class Meta:
model = Client
I need to create a log entry for each filter added or removed from the form. I am new to Python/django but haver been programming for a long time, so its not the algorithm I need, its the Python code to implement it. I know I need to override the forms save method, but I am unclear what internal values to use.