I have this ModelForm
class ScheduleForm(forms.ModelForm):
class Meta:
model = Schedule
fields = ['name', 'involved_people',]
def __init__(self, user, *args, **kwargs):
super(ScheduleForm, self).__init__(*args, **kwargs)
self.fields['involved_people'].queryset = Profile.objects.exclude(user=user)
This is my view
def create_schedule(request):
form = ScheduleForm(request.POST or None)
schedules = Schedule.objects.all().order_by('deadline_date')
if form.is_valid():
schedule = form.save(commit=False)
schedule.save()
messages.success(request, "Schedule added successfully!")
return render(request, 'schedule/index.html', {'schedules': schedules})
context = {'form': form}
return render(request, 'schedule/create_schedule.html', context)
How do you pass request.user in the view?
How do you initialize the form with request.user in it?
You have added user to the __init__ method,
def __init__(self, user, *args, **kwargs):
so now you just pass the user as the first argument when you instantiate your form.
form = ScheduleForm(request.user, request.POST or None)
Related
I am building a CRM where I want each client to have multiple plans, and each plan to have multiple notes. When a user creates a new note, I want them to be able to select a relevant plan from a dropdown of plans belonging to the client. From what I can find, I should be able to get the contact_id from the kwargs, but my errors show nothing in kwargs. I know there should be a way to do this, but I can't seem to find it.
Variable Value
__class__ <class 'lynx.forms.SipNoteForm'>
args ()
kwargs {}
self <SipNoteForm bound=False, valid=Unknown, fields=(sip_plan;note;note_date;fiscal_year;quarter;class_hours;instructor;clients)>
Views.py
#login_required
def add_sip_note(request, contact_id):
form = SipNoteForm()
if request.method == 'POST':
form = SipNoteForm(request.POST)
if form.is_valid():
form = form.save(commit=False)
form.contact_id = contact_id
form.user_id = request.user.id
form.save()
return HttpResponseRedirect(reverse('lynx:client', args=(contact_id,)))
return render(request, 'lynx/add_sip_note.html', {'form': form})
Forms.py
class SipNoteForm(forms.ModelForm):
class Meta:
model = SipNote
exclude = ('created', 'modified', 'user', 'contact')
def __init__(self, *args, **kwargs):
super(SipNoteForm, self).__init__(*args, **kwargs)
self.fields['sip_plan'].queryset = SipPlan.objects.filter(contact_id=kwargs.get("contact_id"))
Urls.py
path('add-sip-note/<int:contact_id>/', views.add_sip_note, name='add_sip_note'),
You are trying to get the kwargs in __init__(self, *args, **kwargs) as
def __init__(self, *args, **kwargs):
contact_id = kwargs.pop('contact_id')
super(SipNoteForm, self).__init__(*args, **kwargs)
self.fields['sip_plan'].queryset = SipPlan.objects.filter(contact_id=contact_id)
But you are not passing contact_id kwargs to the form while posting. you should pass kwargs to the form you are going to get in __init__(self, *args, **kwargs) such as
#login_required
def add_sip_note(request, contact_id):
form = SipNoteForm()
if request.method == 'POST':
form = SipNoteForm(request.POST, contact_id=contact_id)
I want to add to my project one feature that only authenticated users can have access their stuff. But when I write queryset it throws an error like ModelNameFormSet object has no request attribute
views.py
class BaseAuthorFormSet(BaseModelFormSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.queryset = Project.objects.filter(author_id=self.request.user.pk)
def add_object(request):
ProjectFormSet = modelformset_factory(Project, formset=BaseAuthorFormSet, fields=( 'service_name', 'service_code', 'report_month', 'report_year', 'last_year'), extra=1)
if request.method == "POST":
form = ProjectFormSet(request.POST)
form.author = request.user
if form.is_valid():
form.save()
form = ProjectFormSet()
return render(request, 'app1/home.html',{'form':form})
I have only this code. How can I solve this issue? Thank you beforehand!
If you need the request in the formset, you need to pass it there. Also note that adding the author to the formset won't do anything, you need to add it to the result of each form save.
class BaseAuthorFormSet(BaseModelFormSet):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
self.queryset = Project.objects.filter(author_id=self.request.user.pk)
def add_object(request):
ProjectFormSet = modelformset_factory(Project, formset=BaseAuthorFormSet, fields=( 'service_name', 'service_code', 'report_month', 'report_year', 'last_year'), extra=1)
if request.method == "POST":
formset = ProjectFormSet(request.POST, request=request)
if formset.is_valid():
for form in formset:
obj=form.save(commit=False)
obj.author = request.user
obj.save()
return redirect('somewhere')
form = ProjectFormSet(request=request)
return render(request, 'app1/home.html',{'form':form})
I have my response form and view like this
class ResponseForm(ModelForm):
class Meta:
model = ResponseModel
exclude = ('author', 'title','submit_count')
# help_texts = {
# 'ans1': user.q1.value,
# }
#login_required
def ResponseFormView(request):
if request.method == "POST":
form = ResponseForm(request.POST)
if form.is_valid():
submission = form.save(commit=False)
submission.author = request.user
submission.save()
return render(request, 'thanks.html', {})
else:
form = ResponseForm()
return render(request, 'response_tem.html', {'form': form})
I want the help text for 'ans1' field to be the value of q1 field of request.user. How do I do it?
You can do it like this:
class ResponseForm(ModelForm):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None) # popping user from known arguments
super(ResponseForm, self).__init__(*args, **kwargs)
if user:
self.fields['ans1'].help_text = "Help Text for {}".format(user.username)
class Meta:
model = ResponseModel
exclude = ('author', 'title','submit_count')
#login_required
def ResponseFormView(request):
if request.method == "POST":
form = ResponseForm(request.POST)
if form.is_valid():
submission = form.save(commit=False)
submission.author = request.user
submission.save()
return render(request, 'thanks.html', {})
else:
form = ResponseForm(user=request.user) # passing user as known argument
return render(request, 'response_tem.html', {'form': form})
Here, in the view I am passing the request.user as known argument when I am initiating Form Class's Object (marked with comment). Then in the Form, I am catching the user sent from view and updating the field's help text.
I am new in Django (1.9)
I have a NOT NULL constraint failed when I save my ModelForm and i don't understand why ...
I propose to the user a form to post a comment and the only field include in the form is "text", i want to set the excluded fields in my view after the validation and before save in database
Models.py :
class Commentaire(models.Model):
text = RichTextField()
pub_date = models.DateTimeField()
author = models.ForeignKey(User)
post = models.ForeignKey(Post)
publish = models.BooleanField()
def __str__(self):
return "/%s/%s" % (self.pub_date,self.author.username)
class Meta:
ordering = ["-pub_date"]
Forms.py :
class CommentaireForm(forms.ModelForm):
class Meta:
model = Commentaire
fields = ['text']
Views.py :
class PostDetail(View):
def get(self, request, *args, **kwargs):
view = PostDisplay.as_view()
return view(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
view = PostComment.as_view()
return view(request, *args, **kwargs)
class PostDisplay(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super(PostDisplay, self).get_context_data(**kwargs)
context['form'] = CommentaireForm()
return context
class PostComment(SingleObjectMixin, FormView):
template_name = 'blogengine/post_detail.html'
form_class = CommentaireForm
model = Post
def post(self, request, *args, **kwargs):
#if not request.user.is_authenticated():
# return HttpResponseForbidden()
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
"""
If the form is valid, redirect to the supplied URL
"""
form.save(commit=False)
form.post = self.object
form.author = self.request.user
form.pub_date = datetime.now()
form.publish = True
form.save()
return HttpResponseRedirect(self.get_success_url())
When Django save the form, i have this exception :
NOT NULL constraint failed: blogengine_commentaire.pub_date
The values i set for the excluded fields (author, post, pub_date) in "form_valid" are not taken into account, they seem to stay NULL
Could you explain me why because i am lost ?
Thanks
You need to rewrite form_valid method like that
def form_valid(self, form):
"""
If the form is valid, redirect to the supplied URL
"""
model_instance = form.save(commit=False)
model_instance.post = self.object
model_instance.author = self.request.user
model_instance.pub_date = datetime.now()
model_instance.publish = True
model_instance.save()
return HttpResponseRedirect(self.get_success_url())
Because save(commit=False) will return you an Post instance that you then need to populate and save.
I have no idea and I need to ask your advice.
I have simple form:
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ['text','author','news']
I want to add form in DetailView and hadle this form there:
class NewsDetailView(DetailView):
model = News
template_name = 'news/detail.html'
def get_initial(self):
return {'news': self.get_object(), 'author': self.request.user}
def get_context_data(self, **kwargs):
context = super(NewsDetailView, self).get_context_data(**kwargs)
context['form'] = CommentForm(initial=self.get_initial())
return context
def post(self, request, *args, **kwargs):
'''
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
comment_form.save()
I don't want to show 'author' and news fieds. But if I hide them I can't to get initial values..
UPDATED:
After form validation I need return current form instance in the template through updating page. I attempted the next:
comment_form = CommentForm(request.POST, request=request)
if comment_form.is_valid() and comment_form.validate_user():
comment_form.save()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
context = super(NewsDetailView,self).get_context_data(**kwargs)
context['form'] = comment_form
return self.render_to_response(context)
But did not work.
If you don't render your fields using {{ form.author }} and {{ form.news }} the form won't validate. Try using a HiddenInput for each field, You can do that by overriding the __init__ method of your form:
class CommentForm(ModelForm):
def __init__(self, *args, **kwargs):
super(CommentForm, self).__init__(*args, **kwargs)
self.fields['author'].widget = forms.HiddenInput()
self.fields['news'].widget = forms.HiddenInput()
class Meta:
model = Comment
fields = ['text','author','news']