I have some form:
class Node(Object):
title = CharField(max_length=255)
body = TextField()
in admin form there is file field (which is a dump,for example csv dump of Nodes)
and what i want to do:
if user fills "data_file" i want to skip all form validation, and create Nodes from data_file content. Otherwise i'll create Node based on "title" and "body fields"
I need help because can not find anything about my problem in django docs
There is method to create a url view, but i want to do it by django standart admin tools
Related
Lets say I've following table:
Table: Posts
Fields: id, name, content
And another table:
Table: Images
Fields: id, post_id, url
Normally, I can create CRUD for each of them. User first create post and save it. Then by Images table CRUD user can add as many as images to posts. But what if requirement is no create CRUD for images. But inside Posts CRUD. I mean while creating (filling Posts fields) there is button which labeled "add images". Then when user add images via that button. Finally when press on "create post" backend code should create both posts and images. How you call it? I couldn't find any tutorial and lesson because of my English I couldn't describe it enough on Google search.
You can use inlines to implement what you want in django admin:
from django.contrib import admin
class ImagesInline(admin.TabularInline):
model = Images
class PostsAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
admin.site.register(Posts, PostsAdmin)
The Django doc mention that a Model AutoField will not be represented in a form built with a ModelForm.
When editing and saving that form, how should I supposed to know the underlying AutoField id value to save correctly my form data to database?
I know I can inject myself in the edit form an hidden field to know which row has been edited but is there a way Django manage that hidden field or some other mecanism automatically?
Thanks a lot
Etienne
You do that by specifying the instance=<> parameter when you are using ModelForm.
More on this in the documentation here
Example usage of a create/update view:
def myview(request, id=None):
if id:
obj_to_edit = MyModel.objects.get(id=1)
form = MyForm(instance=obj_to_edit)
else:
obj_to_edit = None
form = MyForm()
if request.method == 'POST':
if id: #update
form = MyForm(request.POST, instance=obj_to_edit)
else: #create
form = MyForm(request.POST)
#rest of the code
and the URL would have something like:
url(r'/blah/create/', 'myview'),
url(r'/blah/edit/(?P<id>[\d+])/', 'myview')
Now, django understands that it needs to edit rather than create new objects.
Also note that if you are using forms.Form, you would have to manually query for the unique fields, or inject the hidden id field as you have mentioned.
Usually when you're editing a form the specific instance that you want to edit will be identified in your URL using either the primary key or a slug field, e.g:
www.example.com/model/edit/6/
or
www.example.com/model/edit/object_slug/
You would then set up your urls.py to pass that parameter to your view, where you would use the example provided by karthkir (I'll use the primary as the example from here)
urls.py
urlpatterns = patterns('',
url(regex=r'^model/edit/(?P<pk>\d+)/$', 'myapp.views.myview', name='add_customer'),
)
views.py
def myview(request, pk):
obj_to_edit = MyModel.objects.get(id=pk)
...
I have a wtforms form
class MyForm(Form):
names = SelectField('name', choices=[])
The choices of names field is built dynamically and rendered in the template by an ajax call. When I submit the form, it raises an exception "not a valid choice". I don't want the form to validate the choices of names field for me. How can I disable the validation?
I did something like this to step around the SelectMultipleField validation in WTForms. It should work the same way with a plain SelectField
class NonValidatingSelectMultipleField(SelectMultipleField):
"""
Attempt to make an open ended select multiple field that can accept dynamic
choices added by the browser.
"""
def pre_validate(self, form):
pass
I simply override the built-in validation.
I was stuck with the same issue. The solution provided by Xealot is great. I found that there is an option to set validation to False using validate_choice=False. I have included an example of both the solutions below.
class NonValidatingSelectField(SelectField):
"""
Attempt to make an open ended select multiple field that can accept dynamic
choices added by the browser.
"""
def pre_validate(self, form):
pass
class MyForm(Form):
names = NonValidatingSelectField('name')
names2 = SelectField('name2', validate_choice=False)
By "I don't want the form to validate the choices", I assume you actually mean "I'm going to do it myself later and doubt the form's ability to do it correctly".
But you are in luck! You can subclass an existing form to add choices dynamically.
class MyForm(Form):
# other fields...
def some_handler(request):
name_choices = build_name_choices()
class RealForm(MyForm):
names = SelectField('name', choices=name_choices)
form = RealForm(request.GET)
form.validate()
This also saves you from the tedium of merging the form's validation and error messages with those you generate yourself later.
I have two models:
class Customer(models.Model):
(...)
class CustomerMemo(models.Model):
(...)
customer = models.ForeignKey(Customer)
text = models.TextField()
And in my admin.py
class MemoInline(admin.StackedInline):
model = CustomerMemo
class Customer(admin.ModelAdmin):
(...)
inlines = (MemoInline,)
I want to make autosave for these inline fields.
I think there should be ajax request every 30 seconds.
But now there two questons:
How to make ajax request which gets requred data from admin page?
How would be better to add admin custom view which handle this ajax request?
I've read about dajax, but I can't get how it could help me with my task.
Thanks
Redefine admin template and add a JS with some function which will gather form data with $(form).serialize() and make an ajax POST to the server. URL for POST can be admin page itself (if you don't mind overwriting the object) or you can write your own view with necesssary form and formsets. Maybe you'll also need to add value of the "Save" button to POST load.
I have some question:
I use django form, and fields like MultipleChoiceField
in view.py I clean data and get GET URL like this
http://localhost:8000/?category=&style=&sex=&brand=ASICS&brand=Be+Positive&low_price=&high_price=
Give me advise, can I regroup brand field and hide empty.
I want getting something like this:
http://localhost:8000/?brand=1+2
And else one question:
How can I set empty value(empty_label) for forms.ModelMultipleChoiceFIeld
forms.py:
brand = forms.MultipleChoiceField(required=False,
widget=forms.SelectMultiple(attrs={'size':1})
)
def __init__(self,app_label=None, *args, **kwargs):
super(Search, self).__init__(*args, **kwargs)
self.fields['brand'].choices = [('', 'All brands')]+[(brand.name, brand) for brand in Brand.objects.all() ]
views.py:
if request.method == 'GET' and request.GET:
form = SearchForm(app_label, request.GET)
if form.is_valid():
brands = form.cleaned_data['brand']
kwargs.update({"brand__name__in": brands})
This is how the browser submits multiple data. It's part of the HTML specification, trying to change it would be folly and technically I can't understand why you would try to care about how your url GET data looks.
That being said, if you want to change the way it submits you'll need javascript to transform the data on form submit. Django has nothing to do with the matter.
Using jQuery for example:
$('#form').submit(function(){
//Get form data
//Transform into my custom set of vars
//Redirect to form's ACTION with my querystring appended.
});
Please keep in mind you will not get any automatic parsing of the values on the Django side. Normally it would turn it into a list for you, but now you're responsible for parsing the 'value+value+value' yourself.
For empty label in forms you could do this -
class SomeForm(forms.Form):
h=forms.CharField(label=u'',widget=forms.TextInput(attrs={'value':'Search'}))
By keeping label as '', you get the label as empty. The attrs are basically the HTML attributes of the form text field.
UPDATE: I didn't understand the first part of your Q, elaborate...