I just created a form for the first time and have some questions regarding the process and where the data is going.
Here are my models, views, forms, urls, and templates files;
The model from models.py:
class Member(models.Model):
member_id = models.SlugField(max_length=10)
name = models.CharField(max_length=200)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
mobile = models.SlugField(max_length=20)
income = models.CharField(max_length=200, choices=INCOME_CHOICES)
education = models.CharField(max_length=200, choices=EDUCATION_CHOICES)
home_district = models.CharField(max_length=200, choices=DISTRICT_CHOICES)
family_spending = models.CharField(max_length=200, choices=FAMILY_SPENDING_CHOICES)
children_spending = models.CharField(max_length=200, choices=CHILDREN_SPENDING_CHOICES)
birth_date = models.DateTimeField('Birthday', blank=True)
comments = models.CharField(max_length=300, blank=True)
def __str__(self):
return self.name
views.py:
def create_a_member_form(request):
if request.method == 'POST':
form = MemberForm(request.POST)
if form is valid():
member_form = form.save()
return HttpResponseRedirect('/complete/')
else:
form = MemberForm()
return render(request, 'member_form.html', {'form': form})
forms.py:
from .models import Member
from django import forms
class MemberForm(forms.ModelForm):
class Meta:
model = Member
fields = '__all__'
urls.py:
urlpatterns = [
url(r'^member_form/$', views.create_a_member_form, name='member_form')
]
The template (member_form.html):
{% load staticfiles %}
<form action="/admin/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
I want to know:
In the template, what does the /admin/ in <form action="/admin/" method="post"> represent? It's where the page redirects to after I click 'Submit', right?
Does the name='member_form' in urls.py represent the name of the HTML template the URL will match to, in thise case member_form.html?
Where is the data created from the form going? I've tried creating Member objects using the form but the new objects do not show up in my admin site under Members (while existing ones do). How do I make sure the objects created from this form do show up in my Admin site under Members?
Thank you.
Yes.
No, it's the name you use in a {% url %} tag if you want to generate a link pointing at that URL. The template is determined by the view itself (in render(request, 'member_form.html',...)).
It's not going anywhere, because your view is posting to /admin/ instead of /member_form/; /admin/ is the index of the admin site which has no code to actually accept your form data.
Note that 1 is basic HTML, and 2 and 3 are basic Django concepts which are covered in the tutorial; you should go and read that.
Related
I'm creating a form where if we register it should save data to the database if the form is valid. otherwise, it should raise an error but it doesn't save data to the database, and also some fields are required but if I submit the form it doesn't even raise the error field is required. but if I register it manually on Django admin pannel it works perfectly fine.
here is my model:
class foodlancer(models.Model):
Your_Name = models.CharField(max_length=50)
Kitchen_Name = models.CharField(max_length=50)
Email_Address = models.EmailField(max_length=50)
Street_Address = models.CharField(max_length=50)
City = models.CharField(max_length=5)
phone = PhoneNumberField(null=False, blank=False, unique=True)
def __str__(self):
return f'{self.Your_Name}'
also, I disabled html5 validation
forms.py
class FoodlancerRegistration(forms.ModelForm):
phone = forms.CharField(widget=PhoneNumberPrefixWidget(initial="US"))
class Meta:
model = foodlancer
fields = "__all__"
views.py:
def apply_foodlancer(request):
form = FoodlancerRegistration()
return render(request, 'appy_foodlancer.html', {"form": form})
and finally Django template
<form method="POST" novalidate>
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="cta-btn cta-btn-primary">Submit</button>
</form>
Thank you for your time/help
You don't have any form saving logic in your view.
Try something like this:
def apply_foodlancer(request):
if request.method == 'POST':
form = FoodlancerRegistration(data=request.POST)
if form.is_valid(): # if it's not valid, error messages are shown in the form
form.save()
# redirect to some successpage or so
return HttpResponse("<h1>Success!</h1>")
else:
# make sure to present a new form when called with GET
form = FoodlancerRegistration()
return render(request, 'appy_foodlancer.html', {"form": form})
Also check that the method of your form in your HTML file is post. I'm not sure if POST also works.
Avoid defining fields in a modelform with __all__. It's less secure, as written in the docs
Completely new to all computer programming and trying to build an app that tracks my smoking habits. The first step was creating a Django model called packs:
class packs (models.Model):
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, blank=False)
num_packs = models.SmallIntegerField(max_length=10)
cost_packs = models.DecimalField(max_digits=6, decimal_places=2)
Next I created a forms.py page and this is where I started getting lost:
from django.forms import ModelForm
from .models import packs
class packsForm(ModelForm):
class Meta:
model = packs
fields = ['num_packs', 'cost_packs']
Of course that led to my failure in HTML trying to render a page that has all the form data:
{%block content%}
<div class = "form_pack">
<h3>FORM PACK</h3>
<p>
<form method="POST" action="."> {% csrf_token %}
<input text="cost_pack" name=cost_pack>
{{ form }}
<input type="submit" value="save"/>
</form>
</p>
</div>
{% endblock %}
To help my view.py looks like this:
def packs_create(request):
form=packsForm(request.POST or None)
if form.is_valid():
return render(request, 'pack/index.htmnl', {'form': form})
Now when I refresh the page I don't get the form. Just the one input i put in.
Can someone help me sort out which path I got lost in and where I need to connect the dots? I believe my forms.py is not complete, but not sure where to progress...
Thanks,
DrKornballer
Just update your views.py and forms.py you will get your form and can save the data entered.
views.py
def packs_create(request):
if request.method == "POST":
form = packsForm(request.POST)
if form.is_valid():
form.save(commit = True)
else:
form = PacksForm()
return render(request, 'pack/index.html', {'form': form})
forms.py
class packsForm(ModelForm):
class Meta:
model = packs
fields = ('num_packs', 'cost_packs')
I am new to Django Python and I am learning how to use Django and passing data from view to template. Now, here is my situation and I really need some help in understanding where i can be doing wrong.
I am trying to pass data from view to template and then parse the object in the view but for some reason nothing is happening in the template. I have printed the registration object in my views.py and it works fine and displays the information that is correct. But when I send the registration object from views to template nothing happens.
models.py
from django.db import models
from datetime import datetime
from django.shortcuts import redirect
# Create your models here.
# Create your models here.
class Registration(models.Model):
first_name = models.CharField(max_length=255, null=True, blank=True)
last_name = models.CharField(max_length=255, null=True, blank=True)
email = models.CharField(max_length=255, null=True, blank=True)
password = models.CharField(max_length=255, null=True, blank=True)
mobilenumber = models.CharField(max_length=255, null=True, blank=True)
created_on = models.DateTimeField(auto_now_add=True, blank=True)
class Meta:
ordering = ('first_name',)
views.py
class Loginview(CreateView):
model = Registration
form_class = LoginForm
template_name = "loginvalentis/valentis_login.html"
def get(self, request):
form = LoginForm()
# returning form
return render(request, 'loginvalentis/valentis_login.html', {'form': form});
def form_valid(self,form):
user_email = form.cleaned_data.get('email')
user_password = form.cleaned_data.get('password')
try:
registration = Registration.objects.get(email=user_email)
print ("registration",registration.mobilenumber)
return redirect('/loginvalentis/home/',{'registration':registration})
except Registration.DoesNotExist:
user_info = None
return redirect('/loginvalentis/login/')
Template result.html --- ('/loginvalentis/home/')
<html>
<body>
<form id="form1">
{% csrf_token %}
<div>
hello world
<form id ="form1">
<ul>
{% for user in registration %}
<li>{{ user.mobilenumber }}</li>
{% endfor %}
</ul>
</form>
</div>
</form>
</body>
</html>
Your problem is with the redirect() function. You are trying to pass the registration object through it, but it doesn't support this, it's *args and **kwargs are simply a parameters for reversing the url, see here:
https://docs.djangoproject.com/en/2.0/topics/http/shortcuts/#django.shortcuts.redirect
You should use some other way to pass it to another view, e.g. pass only it's id as a parameter of that view's url (you will have to change the url conf appropriatelly), the other way is to use sessions etc.
see:
https://docs.djangoproject.com/en/2.0/topics/http/sessions/
https://docs.djangoproject.com/en/2.0/topics/http/urls/
But really, it would be much easier for you just to walk through this tutorial very carefully
https://docs.djangoproject.com/en/2.0/intro/tutorial01/ trust me, it will be really worth your time, because from your question I can easily tell that you just don't understand what you are doing.
I am pretty new to Django but have gone through a few tutorials and have taken it upon myself to create an app very similar to the Tango with Django walkthrough app, rango.
Everything has worked so far, but when I attempt to add a registration feature, the link brings me to the wrong template. I think this be because I have migrated parts from another app and so perhaps the webpage is looking for something that isn't there?
Here is my forms.py:
from django import forms
from django.contrib.auth.models import User
from address_book.models import Client, UserProfile
class ClientForm(forms.ModelForm):
name = forms.CharField(max_length=128, help_text="Name: ")
phone = forms.IntegerField(help_text="Phone Number: ")
address = forms.CharField(max_length=128, help_text="Address: ")
desired_weight = forms.IntegerField(help_text="Desired Weight: ")
start_weight = forms.IntegerField(help_text="Start Weight: ")
views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
slug = forms.CharField(widget=forms.HiddenInput(), required=False)
comments = forms.CharField(max_length=500, help_text="Comments: ")
# An inline class to provide additional information on the form.
class Meta:
# Provide an association between the ModelForm and a model
model = Client
fields = ('name', 'phone', 'address', 'desired_weight', 'start_weight',)
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password')
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('website', 'picture')
models.py
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
class Client(models.Model):
name = models.CharField(max_length=128, unique=True)
phone = models.IntegerField(default=0)
desired_weight = models.IntegerField(default=0)
start_weight = models.IntegerField(default=0)
address = models.CharField(max_length=128, blank=True)
comments = models.CharField(max_length=500, blank=True)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Client, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
class UserProfile(models.Model):
# This line is required. Links UserProfile to a User model instance.
user = models.OneToOneField(User)
# The additional attributes we wish to include.
website = models.URLField(blank=True)
picture = models.ImageField(upload_to='profile_images', blank=True)
# Override the __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.user.username
views.py
from django.http import HttpResponse
from django.shortcuts import render
from address_book.forms import ClientForm, UserForm, UserProfileForm
from address_book.models import Client
def index(request):
client_list = Client.objects.all().order_by('name')
# Construct a dictionary to pass to the template engine as its context.
# Note the key boldmessage is the same as {{ boldmessage }} in the template!
context_dict = {'clients': client_list}
# Return a rendered response to send to the client.
# We make use of the shortcut function to make our lives easier.
# Note that the first parameter is the template we wish to use.
return render(request, 'address_book/index.html', context_dict)
def add_client(request):
# A HTTP POST?
if request.method == 'POST':
form = ClientForm(request.POST)
# Have we been provided with a valid form?
if form.is_valid():
# Save the new category to the database.
form.save(commit=True)
# Now call the index() view.
# The user will be shown the homepage.
return index(request)
else:
# The supplied form contained errors - just print them to the terminal.
print form.errors
else:
# If the request was not a POST, display the form to enter details.
form = ClientForm()
# Bad form (or form details), no form supplied...
# Render the form with error messages (if any).
return render(request, 'address_book/add_client.html', {'form': form})
def client(request, client_name_slug):
# Create a context dictionary which we can pass to the template rendering engine.
context_dict = {}
try:
# Can we find a category name slug with the given name?
# If we can't, the .get() method raises a DoesNotExist exception.
# So the .get() method returns one model instance or raises an exception.
client = Client.objects.get(slug=client_name_slug)
context_dict['client_name'] = client.name
context_dict['client_name_slug'] = client_name_slug
context_dict['client_phone'] = client.phone
context_dict['client_address'] = client.address
context_dict['desired_weight'] = client.desired_weight
context_dict['start_weight'] = client.start_weight
context_dict['comments'] = client.comments
# Retrieve all of the associated pages.
# Note that filter returns >= 1 model instance.
# pages = Page.objects.filter(category=category)
# Adds our results list to the template context under name pages.
# context_dict['pages'] = pages
# We also add the category object from the database to the context dictionary.
# We'll use this in the template to verify that the category exists.
context_dict['client'] = client
except Client.DoesNotExist:
# We get here if we didn't find the specified category.
# Don't do anything - the template displays the "no category" message for us.
pass
# Go render the response and return it to the client.
print context_dict
return render(request, 'address_book/client.html', context_dict)
def register(request):
# A boolean value for telling the template whether the registration was successful.
# Set to False initially. Code changes value to True when registration succeeds.
registered = False
# If it's a HTTP POST, we're interested in processing form data.
if request.method == 'POST':
# Attempt to grab information from the raw form information.
# Note that we make use of both UserForm and UserProfileForm.
user_form = UserForm(data=request.POST)
profile_form = UserProfileForm(data=request.POST)
# If the two forms are valid...
if user_form.is_valid() and profile_form.is_valid():
# Save the user's form data to the database.
user = user_form.save()
# Now we hash the password with the set_password method.
# Once hashed, we can update the user object.
user.set_password(user.password)
user.save()
# Now sort out the UserProfile instance.
# Since we need to set the user attribute ourselves, we set commit=False.
# This delays saving the model until we're ready to avoid integrity problems.
profile = profile_form.save(commit=False)
profile.user = user
# Did the user provide a profile picture?
# If so, we need to get it from the input form and put it in the UserProfile model.
if 'picture' in request.FILES:
profile.picture = request.FILES['picture']
# Now we save the UserProfile model instance.
profile.save()
# Update our variable to tell the template registration was successful.
registered = True
# Invalid form or forms - mistakes or something else?
# Print problems to the terminal.
# They'll also be shown to the user.
else:
print user_form.errors, profile_form.errors
# Not a HTTP POST, so we render our form using two ModelForm instances.
# These forms will be blank, ready for user input.
else:
user_form = UserForm()
profile_form = UserProfileForm()
# Render the template depending on the context.
return render(request,
'address_book/register.html',
{'user_form': user_form, 'profile_form': profile_form, 'registered': registered} )
register.html
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}Register{% endblock %}
{% block body_block %}
<h1>Register with 3010 Weightloss !</h1>
{% if registered %}
Return to the homepage.<br />
{% else %}
Rango says: <strong>register here!</strong><br />
<form id="user_form" method="post" action="/address_book/register/"
enctype="multipart/form-data">
{% csrf_token %}
<!-- Display each form. The as_p method wraps each element in a paragraph
(<p>) element. This ensures each element appears on a new line,
making everything look neater. -->
{{ user_form.as_p }}
{{ profile_form.as_p }}
<!-- Provide a button to click to submit the form. -->
<input type="submit" name="submit" value="Register" />
</form>
{% endif %}
{% endblock %}
urls.py
from django.conf.urls import patterns, url
from address_book import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^add_client/$', views.add_client, name='add_client'),
url(r'^(?P<client_name_slug>[\w\-]+)/$', views.client, name='client'),
url(r'^register/$', views.register, name = 'register'),
)
index.html
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}Index{% endblock %}
{% block body_block %}
<head>
<title>Rango</title>
</head>
<body>
<h2>Current Clients:</h2>
{% for client in clients %}
<li>{{ client.name }}</li>
{% endfor %}
</body>
{% endblock %}
and finally my base.html:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Address_book</title>
</head>
<body>
{% block body_block %}{% endblock %}
</body>
<h2> Need to make changes? </h2>
<ul>
<li>Add new client</li>
<li>Register here</li>
</ul>
</html>
Like I said above, when I click the link to register in index.py, it brings me to another template, client.html.
It looks like the problem is that /address_book/register/ matches your client url, which comes before the register URL. To fix that, one way to fix this would be to switch the order of the URL strings:
# urls.py
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^add_client/$', views.add_client, name='add_client'),
url(r'^register/$', views.register, name = 'register'),
url(r'^(?P<client_name_slug>[\w\-]+)/$', views.client, name='client'),
)
However, it would be better to call the URL by its name in your base.html instead of relying on the order of the URL strings:
# base.html
...
<li>Register here</li>
...
I'm a Django beginner. I think my problem is trivial but I can't solve it.
I have a model named Document with one FileField:
class Document(models.Model):
file = models.FileField(upload_to="documents")
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
category = models.ForeignKey(DocumentCategory)
title = models.CharField(max_length=255, unique=True)
description = models.TextField()
def __unicode__(self):
return self.title
I want to add a new instance to this class by this ModelForm:
class DocumentForm(ModelForm):
class Meta:
model = Document
In views.py I have:
def add_document(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
return render_to_response('add_document.html', {'form':form}, context_instance=RequestContext(request))
else:
form = DocumentForm()
return render_to_response('add_document.html', {'form':form}, context_instance=RequestContext(request))
Template for this (i.e. add_document.html):
{% extends "base.html" %}
{{block content %}
<form enctype="multipart/form-data" method="post" action="">{% csrf_token %}
{{form}}
<input type="submit" value="Add document" />
</form>
{% endblock %}
In the Admin Interface adding a model to the database is working correctly and adding a file is in "upload_to" localization. My form does not work. When I try to submit a form I get Filefield error: "This field is required!" Without FileField in model this works before.
I have Django 1.2.5
I torture with it for 3 days and nothing! I'm desperate. Sorry for my language. Please help!
As it is now, a file is required. Are you trying to save the form without a file?
If you want to make the file optional, you need to define it in this way:
class Document(models.Model):
file = models.FileField(upload_to="documents", blank=True, null=True)
As a an additional note, the action parameter you have in the form may be incorrect.
It should be an URL; usually in Django you would want to put ".", but not a completely empty string (""). That said, I do not know if this may be an issue or not.
In you Document model, you have your file set to upload_t0 "documents", but where exactly is upload_to pointed to.
May be this will help.