i used a self relationship inside model with foreignkey , purpose was to make a replyable comment , but idk how to use it in templates,
i mean whats different between 3 ManyToOne relationships i used in template , how can i know form send reply or comment?
model:
class Comment(models.Model):
#comments model
post = models.ForeignKey(Post,related_name='comments',on_delete=models.CASCADE)
text = models.CharField(max_length=300)
user = models.ForeignKey(get_user_model(),related_name='users',on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
parent = models.ForeignKey('self', null=True,related_name='reply',on_delete=models.SET_NULL)
class Meta():
verbose_name_plural = 'Comments'
ordering = ['date']
def __str__(self):
return self.test[:50]
template:
<div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button value="submit">Send</button>
</form>
</div>
<div>
{% for comment in object.comments.all %}
<p>{{ comment.text }}</p>
{% for reply in object.reply.all %}
<p>{{ reply.text }}</p>
{% endfor %}
<form method='post'>
{% csrf_token %}
{{ form.as_p }}
<button value="submit">reply</button>
</form>
{% endfor %}
</div>
{% endblock %}
can you a little explain how it works?
You can consider using a recursive solution in your code using with template tag, like this:
First define a template which will render the comment:
<!-- comments.html -->
{% for comment in comments %}
<p>{{ comment.text }}</p>
<form method='post'>
{% csrf_token %}
{{ form.as_p }}
<button value="submit">reply</button>
</form>
{% if comment.reply.exists %}
<ul>
{% include "comments.html" with comments=comment.reply.all %}
</ul>
{% endif %}
{% endfor %}
Then include it in the original template:
<div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button value="submit">Send</button>
</form>
</div>
<div>
{% include "comments.html" with comments=object.comments_only %}
</div>
Finally, only send the Comments which does not have parents,like this:
class Post(...):
...
def comments_only(self):
return self.comments.filter(parent__isnull=True)
Related
forms.py
class UserRegistratiion(forms.Form):
email = forms.EmailField()
name = forms.CharField(help_text="80 Char Maximum")
views.py
def showFormData(request):
fm = UserRegistratiion(auto_id="my_%s")
return render(request, "blog/login.html", {"form":fm})
When i use this in my template it works fine and my help_text shows in span tag..
<form action="">
<div>
{{form.as_p}}
</div>
But, whwn i use for loop
{% for field in form.visible_fields %}
<div>
{{field.label_tag}}
{{field}}
</div>
{% endfor %}
help_text doesn't show how can i get this?
try this
{% for field in form.visible_fields %}
<div>
{{ field.label_tag }}
{{ field }}
{{ field.help_text }} <!-- new -->
</div>
{% endfor %}
or
{% for field in form.visible_fields %}
<div>
{{ field.label_tag }}
{{ field }}
{% if field.name =='name' %}
{{ field.help_text }} <!-- new -->
{% endif %}
</div>
{% endfor %}
I want 3 instance of a URL input form so I can submit up to 3 different URLs.
forms.py
class AdditemForm(forms.Form):
url = forms.URLField(
label='Add Item',
widget=forms.URLInput(
attrs={
"class": "form-control",
}))
view.py
def ItemDetail(request, pk):
listitem = comparelist.objects.get(id=pk)
if request.method == 'POST':
form = AdditemForm(request.POST)
if form.is_valid():
url = form.cleaned_data.get("url")
items.objects.create(
link=url,
name=product_name,
price=price,
store=store,
)
return HttpResponseRedirect(request.path_info)
else:
form = AdditemForm()
template = 'itemdetail.html'
context = {
"comparelist": listitem,
"form": form,
}
return render(request, template, context)
I'm using a form snippet I found in a tutorial:
{% load widget_tweaks %}
<form method="post" class="form">
{% csrf_token %}
{% for hidden_field in form.hidden_fields %}
{{ hidden_field }}
{% endfor %}
{% if form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% for field in form.visible_fields %}
<div class="form-group">
{{ field.label_tag }}
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="form-control is-invalid" %}
{% for error in field.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field field class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field field class="form-control" %}
{% endif %}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
So how do I get 3 of those forms on my page and be able to submit 3 different URLs?
I can only think of having to create 3 different form classes and paste the form snippet 3 times into the template. But that seems like a lot of unnecessary repetition.
Why "create 3 different form classes" ??? You can just create three instances of the same form.
paste the form snippet 3 times into the template
Ever heard about lists and loops ? You can put the three (or more) forms in a list and loop over it.
BUT that's actually not the best solution here - Django has Formsets for this use case.
As you can see the help text is not being rendered as UL instead its just plain text
Here is my code
Forms.py:
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = CustomUser
now = datetime.datetime.now()
fields = ('username', 'email', 'gender', 'security_question', 'answer', 'birth_date', 'resume')
widgets={
'birth_date' :DatePickerInput(
options={
'maxDate':str(datetime.datetime.now()),
}
)
}
Views.py:
class SignUp(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'users/signup.html'
signup.html:
{% extends 'base.html' %}
{% block title %}Sign Up{% endblock %}
{% block content %}
<div class="login-page">
<h1>Sign up</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<!--
{{ form.as_p }}
-->
<div class="form">
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
</div>
</form>
</div>
{% endblock %}
Can someone help me figure out how do i Fix the issue ? i am using Django2.0.6
help_text is allowed to contain HTML - but you are rendering it as a safe string - you need to use the safe template filter to allow the HTML to be rendered.
You are also rendering it inside a <small> tag which will result in invalid HTML if the help text contains a list, as it does in this case.
I'd suggest you consider refactoring your template do handle this - e.g.:
{% if field.help_text %}
<div style="color: grey">{{ field.help_text|safe }}</div>
{% endif %}
You might also want to consider using styled classes instead of inline styling for these elements.
If you don't want HTML to appear in the help_text then you will need to modify the help_text of the field in question.
I have a model form and I wanted to know if it is possible to take a model form and assign the name of the specific field when it is running through a for loop within the template html file.
Here is what i have in the current html template:
{% extends "base.html" %}
{% block content %}
<h1>Add members to {{record.name}}</h1>
{% if message %}
<p>{{message}}</p>
{% endif %}
<form action="." method="POST">
{% csrf_token %}
{% for trans in transactions %}
{% if trans.record.id == record.id %}
{{ trans.user.username }}
{{ form.as_p }}
{% endif %}
{% endfor %}
<p>Tax: <input type="text" name="tax" value=""></p>
<p>Tip: <input type="text" name="tip" value=""></p>
<input type="submit" name="submit" value="submit">
</form>
{% endblock %}
here is the current form model:
class IndividualSplitTransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ['amount', 'description']
currently the format is looking like this:
omar
amount
description
hani
amount
description
assad
amount
description
tax
tip
so when i process it and i want to grab the amount assigned to each of the specific users and update a record. I want it to look something like this for easier processing in the view.
omar
omaramount
omardescription
hani
haniamount
hanidescription
assad
assadamount
assaddescription
tax
tip
so that when i am processing I can properly assign the corrent amount and description for each user when i am updating existing records with the amount.
is it possible to do that within the template itself or would i have to do it somewhere else.
UPDATED
So i tried to change my code and update it to get what i am trying to get but this is what i am getting...
Here is the html
{% extends "base.html" %}
{% block content %}
<h1>Add members to {{record.name}}</h1>
{% if message %}
<p>{{message}}</p>
{% endif %}
<form action="." method="POST">
{% csrf_token %}
{% for trans in transactions %}
{% if trans.record.id == record.id %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ trans.user.username }}{{ field.label }}{{ field|safe }}
</div>
{% endfor %}
{% endif %}
{% endfor %}
<p>Tax: <input type="text" name="tax" value=""></p>
<p>Tip: <input type="text" name="tip" value=""></p>
<input type="submit" name="submit" value="submit">
</form>
{% endblock %}
and here is what I am getting.
request returs
So if you look at the image, it is still just returning the last amount and description of the three that i entered... should i just create the whole form manually in the html file....
If you wanted the username + amount or username + description, then you to change away from form.as_p, because you will get the html <p><p/> tag for each field with label preceding it.
You want to dynamically add username then do by designing your own html content of the form manually.
There is a label_suffix, but prefix is not available. Even with suffix you should be doing it at the time of creating the form object.
Update:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ trans.user.username }} {{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
I am trying to create a FormWizard to add multiple instances of a model at once. The second page is dynamic, based on the number to be added, and creates a single "serial number" field - the differentiating factor between all the instances.
I'm getting the first page of the wizard fine, but the second page - the dynamic one - is giving me this Validation Error:
[u'ManagementForm data is missing or has been tampered.']
All the searching I've done points to a formset issue, which I'm not using. What have I done wrong?
forms.py
class CarrierWizardForm1(forms.Form):
part_numbers = forms.ModelChoiceField(queryset=PartNumber.objects.all())
expiry_date = forms.DateField()
qty_at_new = forms.IntegerField()
unit_cost = forms.DecimalField(max_digits=10, min_value=0, decimal_places=3)
cost_currency = forms.ChoiceField(choices=CURRENCY_CHOICES)
class CarrierWizardForm2(forms.Form):
def __init__(self, *args, **kwargs):
qty = kwargs.pop('qty')
super(CarrierWizardForm2,self).__init__(*args,**kwargs)
for i in qty:
self.fields['serial_%s' % i] = forms.CharField(max_length=45)
The defs in CarrierWizardForm2 is a fairly common idiom that is noted all over the web as a solution to this problem, including by Jacobian Nor is their anything crazy in urls
urls.py
carrier_wizard_forms = [CarrierWizardForm1, CarrierWizardForm2]
...
url(r'^carrier/add/$', views.CarrierCreateWizard.as_view(carrier_wizard_forms)),
My views are relatively complex, but nothing outrageous. Note there are some fields that aren't in the forms - they are filled with context data (user, creation date, etc)
views.py
TEMPLATES = {"0": "inventory/carrier_wizard_form1.html",
"1": "inventory/carrier_wizard_form2.html"}
class CarrierCreateWizard(SessionWizardView):
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
''' Get the qty from form 1 to indicate how many fields
form2 needs for serial numbers
'''
def get_form_initial(self, step):
current_step = self.storage.current_step
if current_step == 'step1':
prev_data = self.storage.get_step_data('step0')
return self.initial_dict.get(step, {'qty': qty})
return self.initial_dict.get(step, {})
def done(self, form_list, **kwargs):
details = form_list[0]
list_of_serial_nos = form_list[1]
for serial_name, serial in list_of_serial_nos.cleaned_data.items():
carrier = Carrier()
carrier.part_numbers = details.cleaned_data['part_numbers']
carrier.creation_date = datetime.datetime.today()
carrier.expiry_date = details.cleaned_data['expiry_date']
carrier.qty_at_new = 1
carrier.qty_current = 1
carrier.serial = serial
carrier.unit_cost = details.cleaned_data['unit_cost']
carrier.cost_currency = details.cleaned_data['cost_currency']
carrier.user = self.request.user
carrier.save()
My second template is bland, although you can see three unsuccessful attempts to rectify this issue.
inventory/carrier_wizard_form2.html
{% extends "base.html" %}
{% block content %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post">{% csrf_token %}
{# Attempt 3 #}
{{ formset }}
{# Attempt 2 {{ form.management_form }}
{% for f in form %}
{{ f.as_p }}
{% endfor %}
#}
{# Attempt 1 {{ form }} #}
<input type=submit>
</form>
{% endblock %}
EDIT
*As requested, both of my templates*
inventory/carrier_wizard_form1.html
{% extends "base.html" %}
{% block content %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post">{% csrf_token %}
{{ wizard.form.as_p }}
<input type=submit>
</form>
{% endblock %}
templates/inventory/carrier_wizard_form2.html
{% extends "base.html" %}
{% block content %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post">{% csrf_token %}
<table>
{{ wizard.form }}
{#
{{ wizard.management_form }}
{% if wizard.form.forms %}..
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form }}.
{% endif %} #}
</table>
<input type=submit>
</form>
{% endblock %}
Your template is not correct, use {{ wizard.management_form }} to add wizard management related stuff and use {{ wizard.form }} for forms.
From the reference doc the template is like:
{% extends "base.html" %}
{% block content %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post">{% csrf_token %}
{{ wizard.management_form }} {#add wizard management data #}
{% if wizard.form.forms %} {# if form is formset #}
{{ wizard.form.management_form }} {#formset's management data #}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form }} {#for normal form #}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans "first step" %}</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "prev step" %}</button>
{% endif %}
<input type="submit" value="{% trans "submit" %}"/>
</form>