Django class based views success_url - django

I am trying to set the success_url on a django class based UpdateView but cannot get it to work. I have tried the syntax suggested in the docs
success_url="/polls/%(slug)s/"
But it is not working. How can I access the model fields in the success_url?

This relies on object field attributes. In the example you've posted, the model should have a slug field.
For related fields:
You can try using django's __ notation for related objects (e.g: user__username) in success_url, not sure if it'll work.
IMO in such cases a better practice is overriding get_success_url(), and returning the url taking into account self.object.

Related

Is it possible to edit the 'field' class variable in Django CBV using URL args?

I am trying to use a CreateView to create a profile object. Depending on the type of profile, though, I want to show a different set of fields. Right now I am passing the type of profile through the url.
How would I go about accessing this argument to filter the types of fields? I know how to do so in something like a get() function in a CBV, but not in the body of the class itself. I also do not know if there is an appropriate function to do this in and have not been able to find a solution in the docs.
Thank you in advance for any help, and I am sorry if this question has an obvious answer that I have missed.
You would need to override some method. Potential methods that can work are get_form_class, get_form, etc. Try overriding get_form:
class MyView(CreateView):
model = SomeModel
fields = None
def get_form(self):
self.fields = ['field1', 'field2'] # set this according to your conditions
# the keyword arguments passed to the view can be accessed by using self.kwargs.get('<key_name>')
return super().get_form()

django generic view update/create: update works but create raises IntegrityError

I'm using CreateView and UpdateView directely into urls.py of my application whose name is dydict. In the file forms.py I'm using ModelForm and I'm exluding a couple of fields from being shown, some of which should be set when either creating or updating. So, as mentioned in the title, update part works but create part doesn't which is obvious because required fields that I have exluded are sent empty which is not allowed in my case. So the question here is, how should I do to fill exluded fields into the file forms.py so that I don't have to override CreateView?
Thanks in advance.
Well, you have to set your required fields somewhere. If you don't want them to be shown or editable in the form, your options are to set them in the view (by using a custom subclass of CreateView) or if appropriate to your design in the save method of the model class. Or declare an appropriate default value on the field in the model.
It would also work to allow the fields into the form, but set them to use HiddenInput widgets. That's not safe against malicious input, so I wouldn't do that for purely automated fields.
You cannot exclude fields, which are set as required in the model definition. You need to define blank=True/null=True for each of these model fields.
If this doesn't solve your issue, then please show us the model and form definitions, so we know exactly what the code looks like.

limit choices for foreign field based on other field

Is it possible to do really dynamic form in AdminModel? I have following models:
class MyModel(models.Model):
firstfield=models.ForeignKey(First)
secondField= models.ForeignKey(Second, blank=True,null=True)
#some other fields
class Second(models.Model):
firstfield=models.ForeignKey(First)
#other fields
As you can see Second is optional. But I want it to limit according to current selection in First? It would require some page refreshing or some ajax work but I simply don't know how to even pass First value. Maybe I should add it to request and then use something similar to:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey ?
You can do it through ajax request. If you don't know how it works see the below links.
How to implement two dropdowns dependent on each other using Django and jQuery
Dynamic select fields with JQuery and django

Django Class-Based Generic Views and ModelForms

Like much documentation on generic views in Django, I can't find docs that explicitly describe how to use the new Class-Based Generic Views with Django Forms.
How is it done?
What have you tried so far? The class based views are pretty new, and the docs don't have a lot of examples, so I think you're going to need to get your hands dirty and experiment!
If you want to update an existing object, then try using UpdateView. Look at the mixins it uses (e.g ModelFormMixin, SingleObjectMixin, FormMixin) to see which methods you can/have to override.
Good luck!
The easiest way to use model forms with class based views is to pass in the model and keep a slug / pk captured in url, in which case you will not need to write any view code.
url(r'^myurl/$', CreateView.as_view(model=mymodel))
#Creates a model form for model mymodel
url(r'^myurl/(?<pk>\w+)/$', UpdateView.as_view(model=mymodel))
#Creates a model form for model mymodel and updates the object having pk as specified in url
url(r'^myurl/(?<slug>\w+)/$', DeleteView.as_view(model=mymodel, slug_field="myfield"))
#Creates a model form for model mymodel and deletes the object denoted by mymodel.objects.get(my_field=slug)
You can also override methods to obtain more complex logic. You can also pass a queryset instead of a model object.
Another way is to create a modelform in forms.py and then pass form_class to the url as
url(r'^myurl/$', CreateView.as_view(form_class=myform))
This method allows you to define form functions as well as Meta attributes for the form.

Model formsets and Date fields

I have a model formset on a model with a couple of date fields - which again is a DateTimeField in the model.
But when it displays in the template, it is shown as a text field.
How can I show it as a drop down box ?
WFormSet = inlineformset_factory(UserProfile, W, can_delete=False,exclude=[<list of fields to be excluded>], extra=3)
This is how I am intializing the modelformset.
How do I override these settings
The usual way to do this is to override the default field types in your ModelForm definition.
The example below would work if you had a DateField in your model (I note you have a DateTimeField... I'll come back to that in a sec). You're going to be specifying the exact same field type as would normally be specified, but you'll pass a different widget to the form field constructor.
from django.db import models
from django import forms
from django.forms.extras import SelectDateWidget
class MyModel(models.Model):
a_date_field = models.DateField()
class MyModelForm(forms.ModelForm):
a_date_field = forms.DateField(widget=SelectDateWidget())
class Meta:
model = MyModel
There isn't, to my knowledge, an equivalent widget provided for the DateTimeField in Django 1.0.x. In this case, you'll want to make a custom widget, perhaps subclassing SelectDateWidget. I note from a quick google on SelectDateTimeWidget that there have been several others who've been making what appear to be the widget you're seeking. I've not used them, so caveat emptor, but something like this SelectDateTimeWidget patch might be a good place to start.
Edit: When using a ModelFormset or InlineModelFormset, you can still achieve this by passing form=MyModelForm to the inlineformet_factory function:
MyModelFormset = inlineformset_factory(MyParentModel, MyModel, form=MyModelForm)
This works because the two model formset factories actually call the regular formset_factory constructor in their own implementations. It's a little hard to figure out because it's not explicitly stated in the docs... rather the Django docs allude to this ability by mentioning in passing that the model formset factories extend the normal formset_factory. Whenever I'm in doubt, I open django/forms/models.py to check out the full signature of the formset factory functions.