So im trying to make this page where i add new category which only has name. But when i try it, i just get a "non-string type" as the name. So it works i guess just doesn't take whatever i give it in my input in html.
HTML:
<input type="text" class="form-control" placeholder="Name" id = "category-create-name" name=
"category_name">
<input type="submit" class="login-button" value="Post">
Model:
class Category(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255, blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Form:
class CategoryCreateForm(forms.ModelForm):
class Meta:
model = Category
fields = ('name',)
widgets = {
'category_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Name', 'id':'category-create-name'}),
}
View:
class CategoryCreateView(CreateView):
form_class = CategoryCreateForm
template_name = 'product/new_category.html'
success_url = '/dashboard/'
There are a couple of things I see here. First in your form. In the widgets attribute of class Meta, the keys in that dictionary need to be a field name that is in your fields attribute. In other words you need to change 'category_name' to 'name'. Second, in your template that is used for the view. You seem to be manually defining a separate input field rather than the one that your view and form are expecting. You should just define the form in your template like this:
<form method="POST">
{% csrf_token %}
{{ form_as_p }}
<input type="submit" class="login-button" value="Post">
</form>
In the template {{ form.as_p }} will take the form that you gave to your view, and automatically create it in the html when it is being rendered to the page.
Related
I need two of the three form fields to be filled in automatically before submitting to the database. Slug is supposed to be filled based on test_name, and user have to be filled based on data about the current user.
Now I can submit the form, but the database entry will not be created.
models.py
class Test(models.Model):
test_name = models.CharField(max_length=100, db_index=True, verbose_name='Test name')
slug = models.SlugField(max_length=100, unique=True, verbose_name='URL')
author = models.ForeignKey(User, db_column="user", on_delete=models.PROTECT)
forms.py
class AddTestForm(forms.ModelForm):
class Meta:
model = Test
fields = ['test_name', 'slug', 'author']
views.py
def ask_test_name(request):
form = AddTestForm(request.POST)
if form.is_valid():
test = form.save(False)
test.slug = slugify(test.test_name)
test.author = request.user
test.save()
return render(request, 'app/ask_test_name.html', {'form': form})
ask_test_name.html
<form action="{% url 'ask_test_name' %}" method="post">
{% csrf_token %}
<p><input type="text" name="test_name" required></p>
<p><input type="hidden" name="slug"></p>
<p><input type="hidden" name="author"></p>
<p><button type="submit">Create</button></p>
</form>
Updated
It seems to me the problem is that the html does not see what model I want to use, but I don't know how to solve it here, I need two fields to be hidden
Remove slug and author from the fields in forms.py and don't include them in your HTML form. That should do the trick. You're only hitting the DB after already assigning values to slug and author, so that shouldn't throw an error.
I am creating comment area and reply to comment area for users. And I using django-ckeditor for this but there is a problem. When I add "reply form" just showing once in the page. Not showing other forms. The reply system its works just its not showing ckeditor(Rich editor).
I am add some photos for better understanding:
second form in same page:
inspect of first form:
my Models:
class UserMessages(models.Model):
postMessages = RichTextUploadingField(null=True, verbose_name="Message")
post = models.ForeignKey(
UserPosts, on_delete=models.CASCADE, verbose_name="Linked Post", null=True)
username = models.ForeignKey(
User, on_delete=models.CASCADE, verbose_name="Username", null=True)
replies = models.ForeignKey("self", blank=True, null=True, on_delete=models.CASCADE)
my Forms:
class MessageForm(forms.ModelForm):
class Meta:
model = UserMessages
fields = ("postMessages",)
widgets = {
"postMessages": forms.TextInput(attrs={"class":"form-control"}),
#And I tried this but not works..
class ReplyFormMessage(forms.ModelForm):
class Meta:
model = UserMessages
fields = ("replies",)
my HTML:
<form method="POST" >
{% csrf_token %}
{{form.media}}
{{ form }}
<input type="hidden" name="replies_id" value="{{ message.id }}">
<input type="submit" value="Reply" class="btn btn-default">
</form>
as for me, ckeditor just using one id for all form in page. So, do you have an idea?
First of all, you cannot use one id for multiple elements in HTML. The purpose of id is to uniquely identify your HTML tags, you can use classes if you want to generalize the tags.
Secondly, make use of Django inline formsets to achieve what you want.
I am trying to figure out how to access fields from a Model that is used as a ForeignKey within the Model that the forms are querying.
Each Room has a form where the user selects a Layout from a dynamic list of possible Layout objects.
1—The HTML forms/room/update/layouts.html
<form class="layouts__form form-horizontal" action="" method="post" enctype="multipart/form-data">
<fieldset class="form__options">
{% csrf_token %}
{% for field in form.layout %}
<div class="layouts__layout">
{{ field.tag }}
{{ field.choice_label }}
<label for="value_{{ forloop.counter0 }}">
<div class="layouts__layout__thumbnail layouts__layout__thumbnail--{{ field.choice_label }}" style="background-image: url('### (I WOULD LIKE TO LOAD 'Layout.thumbnail' HERE) ###');"></div>
</label>
</div>
{% endfor %}
<div class="form__submit">
<button type="submit">Submit</button>
</div>
</fieldset>
</form>
2—The form is being called by this in views.py:
class RoomLayoutView(UpdateView):
model = Room
form_class = RoomLayoutForm
template_name = 'forms/room/update/layouts.html'
3—Which is being created by this in forms.py:
class RoomLayoutForm(forms.ModelForm):
layout = forms.ModelChoiceField(
widget=forms.RadioSelect(attrs={'type': 'radio', 'id': 'value',}),
queryset=Layout.objects.all(),
required=False, empty_label=None)
class Meta:
model = Room
fields = ['layout']
4—Which uses the Room model from:
class Room(models.Model):
title = models.CharField(max_length=200, blank=True)
layout = models.ForeignKey(Layout, related_name='template_selected', blank=True, null=True)
def __str__(self):
return self.title
5—Which takes one of the Layout models as a ForeignKey defined here:
class Layout(models.Model):
title = models.CharField(max_length=200)
...
padding_top = models.IntegerField(blank=False, default=0)
...
thumbnail = models.FileField(upload_to='layouts')
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-title',)
def __str__(self):
return self.title
I am trying to figure out how to access attributes from Layout model within the actual form. I would especially like to dynamically load the Layout.thumbnail or Layout.padding_top within the form at the top. I have tried at least 8 different methods and was unable to figure out a way to make this work. Any help would be really appreciated.
As stated in this answer, you can access the current instance associated with the form like this in your template:
{{ form.instance }}
So to access the thumbnail or padding_top attributes of the linked layout:
{{ form.instance.layout.thumbnail }}
{{ form.instance.layout.padding_top }}
I have a Comment Model that uses ContentType and GenericForeignKey so that a comment can be attached to an instance of an arbitrary model:
class Comment(models.Model):
...
text = models.TextField()
target_content_type = models.ForeignKey(ContentType, related_name='comment_target',
null=True, blank=True)
target_object_id = models.PositiveIntegerField(null=True, blank=True)
target_object = GenericForeignKey("target_content_type", "target_object_id")
And I have a form for creating Comments:
class CommentForm(forms.Form):
new_comment = forms.CharField(widget=forms.Textarea(attrs={'rows':2}))
The form is used like this:
<form method="POST" action="{% url 'comments:create' %}">{% csrf_token %}
{{ form | crispy }}
<input type='hidden' name = 'target_id' value='{{q.id}}' />
<input type='submit' class='btn btn-primary' value='Add reply' />
</form>
In my Create view, how can I get the model of the originating object, or the ContentType & id, so that I can create a new Comment?
def comment_create(request):
if request.method == "POST":
if form.is_valid():
text = form.cleaned_data.get('new_comment')
target_object_id = request.POST.get('target_id')
target_content_type = ?
...
When you generate the form, add a hidden field that also includes the content type id.
From there you can then query the in-built Django ContentType model, like so:
from django.contrib.contenttypes.models import ContentType
my_model = ContentType.objects.get(id=some_id).model_class()
As for how to get the content type id in there, because you can't use methods that take arguments you can either change how your form is constructed (adding a hidden field and populating a default (better way) or creating a template tag that would act as a helper function to populate a hidden field in the html template (easier way).
In either case, you can then just use the ContentType again to call this:
ct = ContentType.objects.get_for_model(my_item)
Credit to this question.
I am trying to do a very simple django webpage where a user fills 2 fields of a form with two numbers, submits them and gets a result at the third field. I am using ModelForms.
For the moment I am only interested in the first part, where the user navigates to the url and is prompted a page with the empty form. I do the following, but the page I see at my browser has no form, and only the submit button. I don't know if that's because the ModelForm I try to embed in the html code is still empty, but I tried to give it default values and it still didn't work.
Any help will be very appreciated! :)
urls.py:
urlpatterns = patterns('',
url(r'^calculator/', views.calculate)
)
models.py:
class Calc(models.Model):
field1 = forms.CharField()
field2 = forms.CharField()
field3 = forms.CharField()
class CalcForm(ModelForm):
class Meta:
model = Calc
views.py:
def calculate(request):
c = CalcForm()
if request.method == 'POST':
#do the math
#return ...
else:
return render_to_response('home.html', {'calculator': c})
home.html:
<form action="/calculator/" method="post">
<table>
{{ calculator }}<!--I also tried .as_p, .as_ul...-->
</table>
<input type="submit" value="Submit" />
</form>
change the following:
class Calc(models.Model):
field1 = forms.CharField()
field2 = forms.CharField()
field3 = forms.CharField()
to
class Calc(models.Model):
field1 = models.CharField(max_length=10)
field2 = models.CharField(max_length=10)
field3 = models.CharField(max_length=10)
Did you ever syncdb with the above code? Because if you would've, it must have thrown an error. This makes me think if your db has the correct tables or not. Make sure you syncdb after the above change.
Also, you should always check if an instance exist, This will also help you troubleshoot that if the object was correctly passed or not:
{% if calculator %}
<h3>Calculation Form</h3>
<form action="/calculator/" method="post">
<table>
{{ calculator }}
</table>
<input type="submit" value="Submit" />
</form>
{% endif %}
Your model should use models.CharField, not forms.CharField.