Model needs to have a value for field "id" before this many-to-many relationship can be used - django-models

I am unable to save a model in Django with a ManyToManyField while inside Django Admin because I don't know how to create the ID in the database first, and then save the data. It's trying to do both at the same time, but I have to separate the two processes, and I don't know how.
I've gone five full pages deep on Google, and there are tons of answers, but nothing that I can relate to my specific use case.
The error message I get when submitting the form that has the ManyToManyField in it:
ValueError: "<Clients: Lowe, Robb>" needs to have a value for field "id" before this many-to-many relationship can be used.
Here's the model I'm using:
class BusinessInfo(models.Model):
id = models.IntegerField(primary_key=True, editable=False)
business_name = models.CharField(blank=True, null=True, max_length=50)
business_address = models.CharField(blank=True, null=True, max_length=50)
business_city = models.CharField(blank=True, null=True, max_length=50)
business_state = models.CharField(choices=STATE_SELECT, null=True, blank=True, max_length=50)
related_person = models.ManyToManyField('Clients', related_name='related_person', null=True, blank=True)
business_zip = models.IntegerField(blank=True, null=True)
business_contact_name = models.CharField(blank=True, null=True, max_length=50)
business_phone = PhoneField(null=True, help_text='Phone Number | <span style="color: red;">Required</span>')
business_email = models.CharField(blank=True, null=True, max_length=50)
And specifically the field I created:
related_person = models.ManyToManyField('Clients', related_name='related_person', null=True, blank=True)
I've also attempted to use django-modelcluster to no avail.
I'm pretty new to Django so if anyone can help me out and use explicit code that would help me a great deal. Thank you!

Related

django -- Display foreign key relation value in django template

I have a ForeignKey relation between two models and I would like to show the related value in the web page
models.py
class ndcc_template(models.Model):
created_by = models.ForeignKey(to=myperso_user, related_name='created_by_user', verbose_name='Créé par', on_delete=models.PROTECT, blank=False, null=True)
class myperso_user(AbstractUser):
location = models.TextField(blank=False, null=True)
template.html
<h4>--- {{ ctx_form.created_by.value }} ---</h4>
At this point I would like to view the user_name and not the user_ID
Thanks a lot for your help

How to link Wagtail and Django models together such that Wagtail field can be display in Django model admin

I am working on job application form functionality.
I have a Wagtail job description page with a link to application form.
So far I have built JobDetailPage model in Wagtail and JobAppliction Django model (as below):
class JobDetailPage(Page):
...
apply_form = models.ForeignKey(
JobAppliction,
on_delete=models.SET_NULL,
null=True)
job_title = models.CharField(max_length=100, blank=False, null=True)
...
class JobAppliction(models.Model):
# job_id = models.ForeignKey(
# 'careers.JobDetailPage',
# blank=False, null=True,
# on_delete=models.SET_NULL,
# related_name='position', )
name = models.CharField(
max_length=255, blank=False, null=True)
email = models.EmailField(blank=False, null=True)
...
The same application form can be used by a number of job offers.
How do I link these two models together such that in the admin I can tell which instance of job application was submitted which position?
My admin model is as below:
class JobApplictionAdmin(ModelAdmin):
model = JobAppliction
menu_label = "Applications"
list_display = ('title', 'email')

how to update more than one database table within one modeladmin form in wagtail?

In my question, there are three related models:
class DicSoftware(index.Indexed, ClusterableModel):
name = models.CharField("软件名称", max_length=255, blank=True)
version = models.CharField("版本号", max_length=255, blank=True)
panels = [MultiFieldPanel([
FieldPanel('name', classname="col10"),
FieldPanel('version', classname="col10"),
], "模拟软件")]
class Simulation(index.Indexed, ClusterableModel):
name = models.CharField("算例名称", max_length=255, blank=True)
software = ParentalManyToManyField('DicSoftware', related_name='模拟软件')
panels = [ MultiFieldPanel([
FieldPanel('name', classname="col10"),
FieldPanel('software', classname="col10"),
], "算例")]
With these two models above, wagtail automatically generate table simulation_software with three fields, id, simulation_id, dicsoftware_id. However, I want to add other two fields in table simulation_software, inputFile and inputFilePath. The model of the final table simulation_software should be:
class SimulationSoftware(index.Indexed, ClusterableModel):
simulation = models.ForeignKey(Simulation, verbose_name="算例", help_text="/admin/home/simulation/", on_delete=models.CASCADE, blank=True, null=True, related_name='+')
software = models.ForeignKey(DicSoftware, verbose_name="模拟软件", help_text="/admin/home/dicsoftware/", on_delete=models.CASCADE, blank=True, null=True, related_name='+')
#把读入的文件内容存入inputJSON
inputFile = models.FileField("初始化参数文件", upload_to="files", default="")
outputFilePath = models.CharField("结果文件存储位置", max_length=255, blank=True)
panels = [MultiFieldPanel([
FieldPanel('simulation', classname="col10"),
FieldPanel('software', classname="col10"),
FieldPanel('inputFile', classname="col10"),
FieldPanel('outputFilePath', classname="col10"),
], "算例输入")]
When users add one simulation, they have to give the information as follows:
simulation name.
specify the software(one or more software) used in this simulation.
In one simulation, there can be one or more sofware. If two software are used in this simulation, users should give these information at the same time:
the first sofware's inputFile and outputFilePath.
the second sofware's inputFile and outputFilePath.
How to manage the models' structure and the input panels for inputFiles and outputFilePaths of the software(one or more software).
Anyone can give me some sugguestions? Wish for your help. Thank you very much!
you can relate the sub-models by adding attribute (page) like this:
page = ParentalKey('SimulationSoftware', related_name='<sub-class>_model', on_delete=models.CASCADE)
in each of subclasses (DicSoftware and Simulation)
and then in the content_panels of main clustarable model, use the related_name attributes of each sub-class: FieldPanel("<sub-class>_model", classname="col10"),

Django model: Get many fields from 2 tables on same foreign key

I have 2 model classes in Django:
class Notification(models.Model):
receiver = models.ForeignKey(User, null=True, blank=True)
content = models.CharField(max_length=500)
object_id = models.IntegerField(blank=True, null=True)
type = models.TextField(max_length=200, blank=True, null=True)
Class Notification stores notification about users activity. Field "content" is like: "welcome you registered Business Course successfully", or "5ASC is your voucher code". Field type stores types of object: course, promotion.
class PaymentTransaction(models.Model):
course = models.ForeignKey(Course)
student = models.ForeignKey(User)
PAYMENT_STATUS = ( SUCCESS, FAILURE, PROCESSING)
payment_status = models.CharField(max_length=50, choices=PAYMENT_STATUS, default=PROCESSING)
In notification pop up, when he clicks to paid Course then go to Course detail page and start learning, when he clicks to unpaid Course then go to Course register page, when he clicks to promotion code then go to promotion code page
How to have a QuerySet return all fields of Notification and PaymentTransaction tables, and condition is Notification.receiver_id = PaymentTransaction.student_id .
For each Course notification, i want to get Course payment status.I did:
user = request.user
p_list = PaymentTransaction.objects.filter(student=user)
n_list = Notification.objects.filter(receiver=user).intersection(p_list)
But it did't work
I can't understand why you create the Models like this but:
I think it should be:
class Book:
title = models.CharField(max_length=500)
price = models.FloatField()
class User:
name= models.CharField(max_length=500)
something = models.CharField()
class Book_User:
user = models.ForeignKey(User)
book = models.ForeignKey(User)
detail = models.CharField()
And i what is noti for?Just show up the list?
~> it should be the list of Book_User in page of user
~> Problem solve

django "Key 'up_file' not found in MultiValueDict: {}"

In my htmlpage I am having 100 fields
I am having a field for upload file which is optional for users.
When i submit the form with the file chosen and few other fields left blank,
it got saved into db.
At the same time when i try to submit the form without choosing the
file to be uploaded,it is raising error as ""Key 'up_file' not found
in ""
--models.py--
class js_details(models.Model):
user = models.ForeignKey(User, unique=True)
fname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
dob = models.CharField(max_length=20, null=True)
sec_email = models.EmailField(max_length=50, null=True)
address1 = models.CharField(max_length=50, null=True)
address2 = models.CharField(max_length=50, null=True)
up_file = models.FileField(upload_to='documents', null=True)
--views.py--
def newpost(request):
if request.method == "POST":
user_id = request.POST.get('user_id')
fname= request.POST.get('fname')
lastname= request.POST.get('lastname')
dob = request.POST.get('dob')
sec_email = request.POST.get('sec_email')
address1 = request.POST.get('address1')
address2 = request.POST.get('address2')
up_file = request.FILES['up_file']
p = js_details(user_id=user_id,fname=fname,lastname=lastname,dob=dob,sec_email=sec_email,address1=address1,address2=address2,up-file=up_file)
p.save()
How to save the form without the file field filled.?
All ur answers are welcomed.
Thanks in advance.
To strictly answer your question : you are using a subscript access on request.FILES (=> request.FILES['up_file']), which indeed raises aKeyErrorif there's no matchinh key. You should userequest.FILES.get('up_file')and check the returned value which will beNoneif the user didn't post a file. Read the Python's doc aboutmappinganddict` for more on these data types.
Now there's another problems with your code. The first one is that you blindly accept any user input without validation, sanitization and data type conversion. Using a ModelForm would take care of this and simplify your code.
Also and as side note, you should really stick to Django / Python naming conventions and use CapCase for your class names.
Here's a fixed version of you're code:
# models.py
class JsDetails(models.Model):
# ForeignKey -> OneToOneField,
# cf https://docs.djangoproject.com/en/1.4/ref/models/fields/#onetoonefield
user = models.OneToOneField(User, unique=True)
fname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
# I assume "dob" means "date of birth"
# so CharField -> DateField
dob = models.DateField(blank=True, null=True)
sec_email = models.EmailField(max_length=50, blank=True, null=True)
address1 = models.CharField(max_length=50, blank=True, null=True)
address2 = models.CharField(max_length=50, blank=True, null=True)
up_file = models.FileField(upload_to='documents', blank=True, null=True)
# forms.py
from .models import JsDetail
from django import forms
class JsDetailForm(forms.ModelForm):
class Meta:
models = JsDetail
# views.py
from .forms import JsDetailForm
from django.shortcuts import redirect, render
def newpost(request):
if request.method == "POST":
form = JsDetailForm(request.POST, request.FILES)
if form.is_valid():
newdetail = form.save()
redirect("/somewhere/to/show/the/result")
# if the form is not valid it will be redisplayed
# to the user with error messages
else:
form = JsDetailForm()
return render(
request,
"your/template.htm",
dict(form=form)
)
There are still problems with this code IMHO but that's still an improvement. I very strongly suggest you take some time doing the Python tutorial and the Django tutorial, it will save you a whole lot of pain and trouble.

Resources