Insert the current user when creating an object in Database? [duplicate] - django

I am writing an application which stores "Jobs". They are defined as having a ForeignKey linked to a "User". I don't understand how to pass the ForeignKey into the model when creating it. My Model for Job worked fine without a ForeignKey, but now that I am trying to add users to the system I can't get the form to validate.
models.py:
from django.db import models
from django import forms
from django.contrib.auth.models import User
class Job(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=50, blank=True)
pub_date = models.DateTimeField('date published', auto_now_add=True)
orig_image = models.ImageField('uploaded image', upload_to='origImageDB/', blank=True)
clean_image = models.ImageField('clean image', upload_to='cleanImageDB/', blank=True)
fullsize_image = models.ImageField('fullsize image', upload_to='fullsizeImageDB/')
fullsize_clean_image = models.ImageField('fullsize clean image', upload_to='fullsizeCleanImageDB/')
regions = models.TextField(blank=True)
orig_regions = models.TextField(blank=True)
class JobForm(forms.ModelForm):
class Meta:
model = Job
In views.py I was creating the objects as follows:
if request.method == 'POST':
form = JobForm(request.POST, request.FILES)
if form.is_valid():
#Do something here
I understand that this passes the form data and the uploaded files to the form. However, I don't understand how to pass in a User to be set as the ForeignKey.
Thanks in advance to anyone who can help.

A typical pattern in Django is:
exclude the user field from the model form
save the form with commit=False
set job.user
save to database
In your case:
class JobForm(forms.ModelForm):
class Meta:
model = Job
exclude = ('user',)
if request.method == 'POST':
form = JobForm(request.POST, request.FILES)
job = form.save(commit=False)
job.user = request.user
job.save()
# the next line isn't necessary here, because we don't have any m2m fields
form.save_m2m()
See the Django docs on the model form save() method for more information.

Try:
if request.method == 'POST':
data = request.POST
data['user'] = request.user
form = JobForm(data, request.FILES)
if form.is_valid():
#Do something here

Related

django - How to upload file to the folder in filefield

i am saving a form with a filefield, and saying upload_to to a user_path from the userprofile. I do not know how to write the view for the form
models.py
def nice_user_folder_upload(instance, filename):
extension = filename.split(".")[-1]
return (
f"{instance.UserProfile.Assigned_Group}/{filename}"
)
class Metadataform(models.Model):
id = models.AutoField(primary_key=True)
Authors_Name = models.CharField(max_length=500, blank=True, null=True)
Document = models.FileField(upload_to=nice_user_folder_upload)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
Assigned_Group= models.CharField(max_length=500, choices=Group_choices, default='Please Select')
def __str__(self):
return self.user.username
views.py
def Metadata_submission(request):
Authors_Name = request.POST["Authors_Name"]
if request.method == 'POST':
form = Fileuploadform(request.POST, request.FILES)
if form.is_valid():
form.save()
return render(request, "home.html")
else:
form = Fileuploadform()
# forms.py
class Fileuploadform(forms.ModelForm):
class Meta:
model = Metadataform
fields = ['Authors_Name','Affliations','Dataset_Creation_Date','Publication_Ref','Embargo_Time','DataGeneration_Type','Methods','Instruments','Software','Models','Device','Configuration','Precursor','Data_Type','Variables','Error_Estimation','Document']
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('Assigned_Group',)
i am getting an AttributeError at /Metadata_submission/
'Metadataform' object has no attribute 'UserProfile'
The problem here I think is you have so many fields here that might not be associated with your Metadataform model (Maybe you haven't posted it in full). I think you should consider reading doc. By the look of it, you are trying to add UserProfile somewhere on your form, which is causing the error.

how to set foreign key for each files while uploading multiple filels?

Here I am trying to upload multiple files but it's not working properly.I got problem while storing the foreign key for each files selected ?
I got this error.
Cannot assign "<property object at 0x04667960>": "MoreImage.image_title" must be a "Gallery" instance.
models
class Gallery(models.Model):
image_title = models.CharField(max_length=100, blank=True, null=True)
image_date = models.DateField(blank=True, null=True)
image = models.ImageField(upload_to='gallery', default='default.png')
class MoreImage(models.Model):
image_title = models.ForeignKey(Gallery, on_delete=models.CASCADE)
images = models.ImageField(upload_to='moreimage', default='default.png')
date = models.DateTimeField(auto_now_add=True)
views
def add_more_image(request):
images = Gallery.objects.all().order_by('-date')
if request.method == 'POST':
form = MoreImageForm(request.POST or None, request.FILES or None)
if form.is_valid():
more = form.save(commit=False)
for file in request.FILES.getlist('image'):
MoreImage.objects.create(image_title=Gallery.pk, images=file)
#for field in request.FILES.keys():
#for form_file in request.FILES.getlist(field):
#img = MoreImage(image_title_id=Gallery.pk,images=form_file)
#img.save()
more.save()
messages.success(request, ' Images added.')
return redirect('admin:add_gallery')
MoreImage Form
class MoreImageForm(forms.ModelForm):
class Meta:
model = MoreImage
fields = '__all__'
First of all, you shouldn't call Gallery.pk because it's won't return anything since it's a class. It should be something like gallary_instance.pk
and I don't think gallary_instance.pk will work for you because you've set commit=False which prevent to save the object into DB.
Try this,
def add_more_image(request):
images = Gallery.objects.all().order_by('-date')
if request.method == 'POST':
form = MoreImageForm(request.POST or None, request.FILES or None)
if form.is_valid():
more = form.save() # remove commit=False
for file in request.FILES.getlist('image'):
MoreImage.objects.create(image_title=more.image_title, images=file)
messages.success(request, ' Images added.')
return redirect('admin:add_gallery')

Unable to create object from form

After changing the field used as the primary key in a model, I now receive an error when trying to create an object from a form.
I have deleted the sqlite database file, everything in the migrations directory, and performed makemigrations and migrate. I do not believe the problem is with the database, rather something in the code no longer functions the same now that I am not using a custom primary key.
As someone new to Django, I suspect I am missing something fundamental but cannot quite identify what that is.
views.py
#login_required
def job_create(request):
client = request.POST.get('client')
form = JobForm(request.POST or None)
form.fields['client'].initial = Client.objects.get(client_name=client)
if request.method == "POST":
if form.is_valid():
form.save()
return JsonResponse({"Success": True})`
models.py
class Client(models.Model):
client_name = models.CharField(max_length=255, unique=True)
def __str__(self):
return self.client_name
class Job(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
job_number = models.CharField(validators=[RegexValidator(regex='^\d{4}$', message='Invalid job number', code='invalid')], max_length=4, unique=True)
job_description = models.CharField(max_length=30)
forms.py
class JobForm(forms.ModelForm):
class Meta:
model = Job
fields = ('client', 'job_number', 'job_description',)`
The above code fails to create and save the object into the database. Below is my attempt to recreate this using the Django shell:
>>> from myproject.models import Client, Job
>>> from myproject.forms import JobForm
>>> client = Client.objects.get(client_name='John')
>>> jobform = JobForm({'client': client, 'job_description':'This is a job description', 'job_number':'4321'})
>>> jobform.errors
{'client': ['Select a valid choice. That choice is not one of the available choices.']}
Database Columns
sqlite> PRAGMA table_info(myproject_job);
0|id|integer|1||1
1|job_number|varchar(4)|1||0
2|job_description|varchar(30)|1||0
3|client_id|integer|0||0
Solution for now
#login_required
def job_create(request):
if request.method == "POST":
client = Client.objects.get(client_name=request.POST.get("client"))
request.POST = request.POST.copy()
request.POST["client"] = client.id
form = JobForm(request.POST)
if form.is_valid():
form.save()
return JsonResponse({"success": "true"})

set slug field form manually in views Django

I'm new in Django and I'm trying to pre fill one of the fields of my form with a slug.
I'm getting the slug from another model. I'm not using ForeignKey because that shows me a list with my objects and I want to save in the form the same slug that I'm using in the url.
Maybe I'm not thinking this right. What should I do?
Thank you!
This are my models:
from django.db import models
class Thing(models.Model):
name = models.CharField(max_length=255,)
rut = models.CharField(max_length=12, blank= True)
cel = models.CharField(max_length=12, blank= True)
slug = models.SlugField(unique=True)
class Control(models.Model):
id_p = models.SlugField()
pa = models.CharField(max_length=3,)
My forms
from django.forms import ModelForm
from collection.models import Thing, Control, Medicamento
class ThingForm(ModelForm):
class Meta:
model = Thing
fields = ('name', 'rut','cel','pet',)
class ControlForm(ModelForm):
class Meta:
model = Control
exclude = ['id_p']
This is what I'm doing in the views
def add_control(request, slug):
thing = Thing.objects.get(slug=slug)
form_class = ControlForm
form_class(initial={'id_p':thing})
if request.method == 'POST':
form = form_class(request.POST)
if form.is_valid():
form.save()
return redirect('thing_detail', slug=thing.slug)
else: form = form_class()
return render(request, 'things/control.html', {
'thing': thing,
'form': form,
})
So, I figure it out!
In views.py, after " if form.is_valid():"
I put this:
prev = form.save(commit=False)
prev.id_p = thing.slug
prev.save()
In that way I put the data in the excluded field before I commit the form.

how to look over all form fields provided and updating the model

I've created a Django view that does 2 things:
Create a new account
Modify a account
Works:
Creating new account and submitting the HTML form data to the database. Also works: showing a prefilled HTML form if user wants to modify an account with the account data that is known in the database.
Doesnt work:
When the user submits his/her form to update an account (user modified the info in the form), nothing is updated in the database.
I know how to update one single static value in the database like so:
a = accounts.objects.filter(pk=account_id).update(name='static value here')
but I don't know how to update the database with all the form data that the user submits when using Django Modelforms. Does anyone knows how to update the database with the submitted form data?
Code
#login_required(login_url='/dashboard/')
def dashboard_accounts_new_modify(request, account_id=None):
if request.method == 'POST':
# POST DETECTED
form = MyModelForm(request.POST, request.FILES)
if account_id:
# POST DETECTED
# ACCOUNT ID FOUND
# USER WANTS TO MODIFY A ACCOUNT
# WITH THIS QUERY I CAN UPDATE 1 STATIC VALUE IN THE DATABASE
# HOW DO I UPDATE THE VALUES FROM THE FORM IN THE DATABASE?? :(
a = accounts.objects.filter(pk=account_id).update(name='static value here')
return HttpResponseRedirect('/dashboard/accounts/')
else:
# POST DETECTED
# ACCOUNT ID NOT FOUND
# USER WANTS TO CREATE A NEW ACCOUNT
if form.is_valid():
if request.POST.get("name").lower() == 'new':
raise Http404("New account name may not be named NEW.")
# DATAHASE QUERY: ADD NEW ACCOUNT TO DATABASE
form.save()
# REDIRECT
return HttpResponseRedirect('/dashboard/accounts/')
elif account_id:
# NO POST DETECTED
# ACCOUNT ID FOUND
# PREFILL FORM WITH DATA
try:
from django.forms.models import model_to_dict
a = accounts.objects.get(pk=account_id)
form = MyModelForm(initial=model_to_dict(a))
except:
raise Http404("Account not found.")
else:
# NO POST DETECTED
# MODIFICATION IS NOT DETECTED
# LOAD EMPTY FORM
form = MyModelForm()
return render(request, 'backend/base_accounts_new.html', {'Title': 'Accounts', 'form' : form})
Model
# Clientdatabase
class accounts(models.Model):
name = models.CharField(max_length=200)
url = models.CharField(max_length=200)
website_title = models.CharField(max_length=200)
website_h1_text = models.CharField(max_length=200)
website_h2_text = models.CharField(max_length=200)
website_search_text = models.CharField(max_length=200)
website_font = models.CharField(max_length=200)
website_footer_left = models.CharField(max_length=600)
website_footer_right = models.CharField(max_length=600)
website_color_code_search_button = models.CharField(max_length=200)
website_color_code_banner = models.CharField(max_length=200)
website_logo_height_pixels = models.PositiveIntegerField()
website_logo_width_pixels = models.PositiveIntegerField()
filepath_favicon = models.FileField()
filepath_logo_vector = models.FileField()
filepath_logo_normal = models.FileField()
filepath_background_1 = models.FileField()
filepath_background_2 = models.FileField(blank=True, null=True)
filepath_background_3 = models.FileField(blank=True, null=True)
filepath_background_4 = models.FileField(blank=True, null=True)
setting_background_1_active = models.BooleanField()
setting_background_2_active = models.BooleanField()
setting_background_3_active = models.BooleanField()
setting_background_4_active = models.BooleanField()
def __str__(self):
return self.name
class AccountsForm(ModelForm):
class Meta:
model = accounts
fields = '__all__'
You can do like:
from django.shortcuts import get_object_or_404
if request.method == 'POST':
if account_id::
account = get_object_or_404(accounts, pk=account_id)
form = MyModelForm(request.POST,request.FILES, instance=account)
if form.is_valid():
...
form.save()
return HttpResponseRedirect('/dashboard/accounts/')
else:
form = MyModelForm(request.POST, request.FILES)
if form.is_valid():
if request.POST.get("name").lower() == 'new':
raise Http404("New account name may not be named NEW.")
form.save()
Learn more about forms here