I have a small problem with adding data to the database in django 2.0.3
I created the following model:
from django.contrib.auth.models import User
class UserInputSignal(models.Model):
name = models.CharField(max_length=512)
author = models.ForeignKey(User, on_delete=models.CASCADE)
input_file = models.FileField(upload_to='signals/', null=True)
I tried to solve the problem using this form:
from django import forms
from .models import UserInputSignal
class UserInputSignalForm(forms.ModelForm):
name = forms.CharField()
input_file = forms.FileField()
class Meta:
model = UserInputSignal
fields = ('name', 'input_file', )
and this view:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate
from .forms import UserInputSignalForm
#login_required
def storage(request):
form = UserInputSignalForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
name = request.POST.get('name')
author = request.POST.get(request.user)
input_file = request.POST.get('input_file')
return redirect('home')
else:
form = UserInputSignalForm()
return render(request, 'storage.html', {'form': form})
In the template I called, I created the form as follows:
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
I am able to load a page with a form, but it does not post data to the database. I would like to add that I am a novice in django and some mechanisms are just plain understandable for me. Can I ask someone for help with this problem?
Before the redirect, call form.save()
Okay, i worked on your code and it works with me with slight modifications:
models.py
class UserInputSignal(models.Model):
name = models.CharField(max_length=512)
author = models.ForeignKey(User, on_delete=models.CASCADE)
input_file = models.FileField(upload_to='signals/', null=True)
objects = models.Manager()
#this returns the name for your modelobject
def __str__(self):
return self.name
forms.py
#excluded the assiging as fields defination is enough in itself
class UserInputSignalForm(forms.ModelForm):
class Meta:
model = UserInputSignal
#this will exclude the formfield it self but the author will be saved as the person who is logged in
exclude = ["author"]
Edited - Views.py
#login_required
def storage(request):
#authentication for author field using request.user
insta = UserInputSignal(author=request.user)
print(request.user)
form = UserInputSignalForm(request.POST or None, request.FILES or None,instance=insta)
if request.method == 'POST':
if form.is_valid():
signal = form.save(commit=False)
signal.save()
return redirect('home')
else:
form = UserInputSignalForm(instance=insta)
return render(request, 'storage.html', {'form': form})
JlucasRs was right to tell you to use form.save(), but you needed to assign form to something and need not use model fields here as forms.py does that for you.
app/Urls.py - Just for reference
urlpatterns = [
path('home/', home, name='home'),
path('storage/', storage, name='storage'),
]
Edit- Admin.py
from .models import PostModel, UserInputSignal
class UserInputSignalAdmin(admin.ModelAdmin):
list_display = ('name', 'author', 'input_file' )
admin.site.register(UserInputSignal, UserInputSignalAdmin)
Add this code in Admin.py if its not there.
Related
I am new to Django and programming in general. I am trying to generate a list of records from a database but with two fields that can be edited.
In the browser it should show a line with the fields:
clientcode, clientname, Reason, comment
Name and description come from the model and are a reference. The user should only be able to capture reason and comments
I have created a forms.py file and a ModelForm. My issue is how do I pass through an individual object. For this example I've limited my dataset to 10 records
In my view file
def home(request):
if request.method == 'GET':
nca = NcaRe.objects.all()[:10]
form = NcaReForm(instance= <what should go in here> )
return render(request, 'NCAComments/home.html', {'form': form, 'nca': nca})
else:
pass
In my model I have a field called primarykey. I'm not sure how to pass this to the form so that I only bring in that record. I have tried looking at the documentation but have not been able to follow it.
My Model py.
from django.db import models
class NcaRe(models.Model):
primarykey = models.IntegerField(blank=True, null=False, primary_key=True)
clientcode = models.CharField(db_column='ClientCode', max_length=200, blank=True, null=True)
clientname = models.CharField(db_column='ClientName', max_length=510, blank=True, null=True)
reason = models.TextField(blank=True, null=True)
comment = models.TextField(blank=True, null=True)
class Meta:
db_table = 'NCA_RE'
Forms.py
from django.forms import ModelForm
from .models import NcaRe
class NcaReForm(ModelForm):
class Meta:
model = NcaRe
fields = ['reason', 'comment']
In html I am trying to loop through and pass the form
{% for n in nca %}
<p> {{n.clientcode}}</p>
<form>
{% csrf_token %}
{{ form }}
</form>
{% endfor %}
In general, you need to just return empty form if the method of request if GET like as form(). I write below sample code that you can do your calculation in after form validation form.is_valid()
views.py
from django.shortcuts import render
from testPhilip.forms import NcaReForm
from testPhilip.models import NcaRe
def home(request):
if request.method == 'GET':
nca = NcaRe.objects.all()[:10]
form = NcaReForm()
elif request.method == 'POST':
form = NcaReForm(request.POST)
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return render(request, 'testPhilip/home.html', {'form': form, 'nca': nca})
You can retrieve the data after form validation in a cleaned format like this:
comment = form.cleaned_data['comment']
Update:
If you want to populate your form fields with values from database or any default values, you can pass them in the 'GET' section as below:
nca_object=NcaRe.objects.get(pk=nca_id)
form=NcaReForm({
'comment':nca_object.comment,
'reason':nca_object.reason,
})
For more information about writing forms refer to Django forms doc
Django 2.0
Python 3.6
I am having trouble with a Django form that is not saving the file that is selected through the form; whenever you select a file to upload, I receive the message "This Field is Required.".
I placed a blank=True and a null=True in the Model FileField to get rid of the same, but whenever I attempt to load the html, I get this error: "The 'copydoc' attirbute has no file associated with it."
I would like for a user to be able to log in, create an entry and upload a file along with said entry. Why doesn't the DB accept the file from the form?
Thank you.
views.py:
from django.shortcuts import render, redirect
from .models import notarizer, CustomUser, notarizerCreateForm
# from .forms import notarizerCreateForm
# Create your views here.
def home(request):
t = 'home.html'
return render(request, t)
def page1(request):
t = 'log1/page1.html'
if request.user.is_authenticated:
logger = notarizer.objects.filter(userziptie=request.user).order_by('-date')
return render(request, t, {'logger': logger})
else:
return redirect(home)
def create_entry(request):
createPath = 'log1/create_entry.html'
if request.method == 'POST':
if request.method == 'FILES':
form = notarizerCreateForm(request.POST, request.FILES)
if form.is_valid():
instance =notarizerCreateForm(
file_field=request.FILES['file']
)
instance.save()
else:
print(form.errors)
else:
form = notarizerCreateForm(request.POST)
if form.is_valid():
form.save()
else:
print(form.errors)
else:
form = notarizerCreateForm()
return render(request, createPath, {'form': form})
create_entry.html:
{% extends "base.html" %}
{% block placeholder1 %}
<div class="form-holder">
<form name="form" enctype="multipart/form-data" method="POST"
action="/create_entry/" >
{% csrf_token %}
{{ form.as_table }}
<input type="submit"/>
</form>
</div>
{% endblock %}
models.py:
from django.db import models
from users.models import CustomUser
from django.forms import ModelForm
# Create your models here.
class notarizer(models.Model):
date = models.DateField(auto_now_add=True)
docName = models.CharField(max_length=25, null=False)
describe = models.TextField(max_length=280)
signee = models.CharField(max_length=25, null=False)
signeeDets = models.TextField(max_length=280)
copydoc = models.FileField(upload_to='users/', blank=True, null=True)
userziptie = models.ForeignKey('users.CustomUser',
on_delete=models.DO_NOTHING, null=True)
def __str__(self):
return "{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}".format(
self.pk,
self.date,
self.docName,
self.describe,
self.signee,
self.signeeDets,
self.userziptie
)
class notarizerCreateForm(ModelForm):
class Meta:
model = notarizer
fields = ['docName','describe','signee','signeeDets', 'copydoc']
There are some things that make the view workflow very weird:
you check request.method, first you check if it is a 'POST' which is a good idea, but then you check if it is 'FILES', there is no HTTP method named FILES, there are only GET, POST, PATCH, PUT, OPTIONS, etc.;
you call form.is_valid() which is again what should happen, but then you create a new Form, and only pass it a single parameter; and
in case of a POST you should not return a rendered page, but redirect to a GET page (for example showing the result). The workflow is typically Post-redirect-get, since if the user refreshes their browser, we do not want to make the same post again.
The workflow should look like:
def create_entry(request):
createPath = 'log1/create_entry.html'
if request.method == 'POST': # good, a post (but no FILES check!)
form = notarizerCreateForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save()
else:
# you probably want to show the errors in that case to the user
print(form.errors)
# redirect to a page, for example the `page1 view
return redirect(page1)
else:
form = notarizerCreateForm()
return render(request, createPath, {'form': form})
i am new in Django, how to save url of the image in db using django. Thank you very much, sorry my english, i am learning too.
views.py
from django.shortcuts import render
from django.views.decorators.http import require_POST
from .models import Cad_component
from django import forms
from django.views.decorators.http import require_http_methods
class register_data(forms.ModelForm):
class Meta:
model = Cad_component
fields = ('title','slug','description','start_date','imagviewe')
def home(request):
imagesData = Cad_component.objects.all()
template_name = 'index.html'
context = {
'imagesData': imagesData
}
return render(request, template_name, context)
def register(request):
if request.method == "POST":
form = register_data(request.POST)
print (form)
if form.is_valid():
datas = form.save(commit=True)
#datas.image.save(request.read['title'],request.read['image'])
datas.save()
else:
form = register_data()
return render(request, 'register.html', {'form': form})
models.py
from django.db import models
import datetime
class ComponentManager(models.Manager):
def search(self, query):
return self.get_queryset().filter(
models.Q(name__icontains=query) | \
models.Q(description__icontains=query)
)
class Cad_component(models.Model):
title = models.CharField('Title', max_length=100)
slug = models.SlugField('Link')
description = models.TextField('Description', blank=True)
start_date = models.DateField('Data: ', null=True, blank=True)
image = models.ImageField(upload_to='img', verbose_name='Imagem', null=True, blank=True)
created_at = models.DateTimeField('Criado em ', auto_now_add=True)
updated_at = models.DateTimeField('Atualizado em', auto_now=True)
objects = ComponentManager()
def __str__(self):
return self.title
I was able to solve this problem, with a configuration that Django does in the HTML file. Just add: enctype = "multipart / form-data" in the FORM tag.
Follow:
<form class="needs-validation" method="post" enctype="multipart/form-data">
Any doubts I am available.
from django.core.files.storage import FileSystemStorage
//inside the view function
myfile = request.FILES['files']
f = FileSystemStorage()
filename = f.save(myfile.name, myfile)
url = f.url(filename)
Now you can store this url.
Give an up if it worked... I am new to stackoverflow.
My problem is similar to how to edit model data using django forms, but I'm not able to solve it.
I would like to get an form with prefielled fields and to allow user to edit them.
I believe my problem is in views.py file, but unfrotuntely I'm not able to solve it.
models.py
from django.db import models
class Item(models.Model):
product = models.CharField(max_length=150)
quantity = models.DecimalField(max_digits=8, decimal_places=3)
price = models.DecimalField(max_digits=7, decimal_places=2)
purchase_date = models.DateTimeField()
warranty = models.DecimalField(max_digits=4, decimal_places=1)
comment = models.TextField()
forms.py
from django import forms
from items.models import Item
class EditItemForm(forms.ModelForm):
class Meta:
model = Item
fields = ('product','quantity', 'price', 'purchase_date', 'warranty', 'comment')
urls.py
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^show_all/$', 'items.views.items'),
url(r'^(?P<item_id>\d+)/$', 'items.views.item'),
url(r'^edit/(?P<item_id>\d+)/$', 'items.views.edit'),
)
edit.html
<form action="/items/edit/" method="post" class="form horizontal well">{% csrf_token %}
{{ form.as_p }}
<imput type="submit" class="btn btn-inverse" value="Aktualizuj">
</form>
views.py
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from items.models import Item
from decimal import Decimal
from django.core.context_processors import csrf
from items.forms import EditItemForm
def edit(request):
if request.method == 'POST':
form = EditItemForm(request.POST, instance=request.item)
if form.is_valid():
form.save()
return HttpResponseRedirect('/items/show_all/')
else:
form = EditItemForm(instance=item)
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('edit.html', args)
Above code is resulting this message:
TypeError at /items/edit/1/
edit() got an unexpected keyword argument 'item_id'
Can you please help me?
Django 1.6, Python 3.4
You've imagined an attribute called request.item. There's no such thing. You need to get the item from the database, via the ID passed into the function as alecxe showed.
def edit(request, item_id):
item = Item.objects.get(pk=item_id)
if request.method == 'POST':
form = EditItemForm(request.POST, instance=item)
edit() view should allow a keyword argument item_id:
def edit(request, item_id=None):
if request.method == 'POST':
...
I'm trying to ask a user some additional info while signing up. I'm using django allauth for authorization and authentication. I try to add three more fields during the signup process. If If I run it, it shows me the standard form plus gender field. However, it doesn't seem to really work. How can I save the data? Could someone help? Thank you in advance!
EDITED: if I just use
if form.is_valid():
form.save()
return redirect('/success/')
I get an error:
save() missing 1 required positional argument: 'user'
I'm quite new to django.
I created signups app in the project.
I put this in allauth_settings.py:
ACCOUNT_SIGNUP_FORM_CLASS = 'signups.forms.MySignupForm'
My signups/model.py:
from django.contrib.auth.models import User
from django.db import models
from allauth.account.models import EmailAddress
from allauth.socialaccount.models import SocialAccount
import hashlib
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
about_me = models.TextField(null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add= True, auto_now=False)
updated = models.DateTimeField(auto_now_add= False, auto_now=True)
GENDER_CHOICES = (
('m', 'Male'),
('f', 'Female'),
)
# gender can take only one of the GENDER_CHOICES options
gender = models.CharField(max_length=1, choices=GENDER_CHOICES,
verbose_name='Gender')
def __unicode__(self):
return self.user.username
class Meta:
db_table = 'user_profile'
def profile_image_url(self):
"""
Return the URL for the user's Facebook icon if the user is logged in via
Facebook, otherwise return the user's Gravatar URL
"""
fb_uid = SocialAccount.objects.filter(user_id=self.user.id, provider='facebook')
if len(fb_uid):
return "http://graph.facebook.com/{}/picture?width=40&height=40".format(fb_uid[0].uid)
return "http://www.gravatar.com/avatar/{}?s=40".format(hashlib.md5(self.user.email).hexdigest())
def account_verified(self):
"""
If the user is logged in and has verified hisser email address, return True,
otherwise return False
"""
if self.user.is_authenticated:
result = EmailAddress.objects.filter(email=self.user.email)
if len(result):
return result[0].verified
return False
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
my signups/forms.py:
from allauth.account.forms import SignupForm
from django import forms
from .models import UserProfile
class MySignupForm(SignupForm):
class Meta:
model = UserProfile
gender = forms.CharField(max_length=1, label='gender')
def save(self, user):
user.gender = self.cleaned_data['gender']
user.save()
my signups/views.py:
from django.template import RequestContext
from django.shortcuts import render_to_response
from .forms import SignupForm
def index(request):
form = MySignupForm(request.POST or None)
if form.is_valid:
???
return render_to_response("signups/index.html", locals(),
context_instance=RequestContext(request))
My index.html is very basic, I just wanted to see the representation of the form:
{% extends 'account/base.html' %}
{% block head_title %}ProjectName{% endblock %}
{% block content %}
<form method="POST" action="">
{{ form.as_p }}
<input type="submit">
</form>
{% endblock %}
You are instantiating the SignupForm, which is the standard form but not your MySignupForm in the view. Change it like this:
def index(request):
form = MySignupForm()
return render_to_response("signups/index.html", locals(),
context_instance=RequestContext(request))