Problem
I'm new in Django, I have a function to retrieve foreign key object in views.py and I want to call this function to models.py, is there any way to do this?
views.py
def get_fk(request):
if request.method == 'POST':
category = itemCategory.objects.get(pk=request.POST.get('idItemCat'))
return category
models.py
class MyUser(AbstractUser):
pass
class ItemCategory(models.Model):
idItemCat = models.CharField(primary_key=True max_length=5)
nameCategory = models.CharField(max_length=150)
class ItemCode(models.Model):
idItemCode = models.CharField(primary_key=True, editable=False, max_length=20)
idItemCat = models.ForeignKey(ItemCategory, on_delete=models.DO_NOTHING)
What I've tried
To import a function usually in django like this from .views import get_fk, but every time I did that it doesn't work and getting this error, it said that my custom user has not been installed.
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'aset_app.MyUser' that has not been installed
Even though in my settings I've already installed my custom user
AUTH_USER_MODEL = 'aset_app.MyUser'
I know to use method request is supposed to be in views.py. But when I've tried to put this function inside models.py I'm getting another error it said
get_fk() missing 1 required positional argument: 'request'
If my question isn't clear enough, please let know...
Related
I've been trying to create this model object but i keep getting this error:
Field 'id' expected a number but got 'create'.
Image of error is shared bellow.
I am using djangi 3.0.3
view.py file:-
from django.shortcuts import render
from . import models
from django.views.generic import (View,TemplateView,ListView,DetailView,
CreateView,UpdateView,DetailView)
# Create your views here.
class IndexView(TemplateView):
template_name = 'index.html'
class SchoolListView(ListView):
context_object_name = 'schools'
model = models.School
class SchoolDetailView(DetailView):
context_object_name = 'school_detail'
model = models.School
template_name = 'basic_app/school_detail.html'
class SchoolCreateView(CreateView):
fields = ('name','principal','location')
model = models.School
model.py
from django.db import models
from django.urls import reverse
# Create your models here.
class School(models.Model):
name = models.CharField(max_length=265)
principal = models.CharField(max_length=256)
location = models.CharField(max_length=256)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("basic_app:detail", kwargs={'pk':self.pk})
class Student(models.Model):
name = models.CharField(max_length=256)
age = models.PositiveIntegerField()
school = models.ForeignKey(School, related_name='student', on_delete=models.CASCADE)
def __str__(self):
return self.name
output error
Any help will be appreciable
Thank & Regards
Viplav Dube
Click here for code imageIf you are using path, in the urls.py in the application folder follow the code on the picture. This fixed the issue for me.
This looks like an error with your urls.py. Just make sure when you mention URL paths in your urls.py the definitive paths come first and variable paths come later. Here for instance, this code will give you an error:
path('<int:id>/' , view.DetailView.as_view(), name="detail")
path('create/' , view.CreateView.as_view(), name="create")
To avoid the error just change the order like this:
path('create/' , view.CreateView.as_view(), name="create")
path('<int:id>/' , view.DetailView.as_view(), name="detail")
This happens so because in the later piece of code django will look for path /create and if it is unable to match it then it will look for path int:id/. Now since int:id/ is a variable if django was to look for it first it would try to assign "create" to id variable which will give a validation issue.
In appurls.py write this
path('<int:pk>/', views.SchoolDetailView.as_view(), name='detail')
I cannot get this to work:
class MyView(generic.ListView):
context_object_name = 'my-model-list'
template_name = 'my_models.html'
def get_queryset(self):
return MyModel.objects.filter(user=self.request.user)
I have also tried
return MyModel.objects.filter(user=User.objects.filter(name=self.request.user))
It seems that self.request.user is returning a name. The error I get is
Cannot query "a": Must be "User" instance.
The user's name is "a".
My model is
from .models import User
class MyModel(models.Model):
user = models.ForeignKey(User)
Can anyone help me?
Thank you in advance.
Your code as shown is correct. The problem is that you are defining your own User class and Django does not know how to handle it when making requests.
The easiest way to do this would be to use the Django User. If you insist on using your own User Class you will need to modify that class to properly inherit from the Django User and a few other things (there are a few StackOverflows on that).
In your ./MyModel/models.py you will want to import User as such:
from django.contrib.auth.models import User
Leave your other models and your views as is (unless they also import User).
You may also have to update your settings file to look something like this (This may not be fully correct):
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
Don't forget to migrate your DB after making these changes.
you are inheriting the User model the wrong way.
Use from django.contrib.auth.models import User instead.
You can use self.request.user.mymodel_set.all() to get all Querys of current user
from .models import User
class MyModel(models.Model):
user = models.ForeignKey(User)
class MyView(generic.ListView):
context_object_name = 'my-model-list'
template_name = 'my_models.html'
def get_queryset(self):
return self.request.user.mymodel_set.all()
I have a model with two entities, Person and Code. Person is referenced by Code twice, a Person can be either the user of the code or the approver.
What I want to achieve is the following:
if the user provides an existing Person.cusman, no further action is needed.
if the user provides an unknown Person.cusman, a helper code looks up other attributes of the Person (from an external database), and creates a new Person entity.
I have implemented a function triggered by pre_save signal, which creates the missing Person on the fly. It works fine as long as I use python manage.py shell to create a Code with nonexistent Person.
However, when I try to add a new Code using the admin form or a CreateView descendant I always get the following validation error on the HTML form:
Select a valid choice. That choice is not one of the available choices.
Obviously there's a validation happening between clicking on the Save button and the Code.save() method, but I can't figure out which is it. Can you help me which method should I override to accept invalid foreign keys until pre_save creates the referenced entity?
models.py
class Person(models.Model):
cusman = models.CharField(
max_length=10,
primary_key=True)
name = models.CharField(max_length=30)
email = models.EmailField()
def __unicode__(self):
return u'{0} ({1})'.format(self.name, self.cusman)
class Code(models.Model):
user = models.ForeignKey(
Person,
on_delete=models.PROTECT,
db_constraint=False)
approver = models.ForeignKey(
Person,
on_delete=models.PROTECT,
related_name='approves',
db_constraint=False)
signals.py
#receiver(pre_save, sender=Code)
def create_referenced_person(sender, instance, **kwargs):
def create_person_if_doesnt_exist(cusman):
try:
Person = Person.objects.get(pk=cusman)
except Person.DoesNotExist:
Person = Person()
cr = CusmanResolver()
Person_details = cr.get_person_details(cusman)
Person.cusman = Person_details['cusman']
Person.name = Person_details['name']
Person.email = Person_details['email']
Person.save()
create_Person_if_doesnt_exist(instance.user_id)
create_Person_if_doesnt_exist(instance.approver_id)
views.py
class CodeAddForm(ModelForm):
class Meta:
model = Code
fields = [
'user',
'approver',
]
widgets = {
'user': TextInput,
'approver': TextInput
}
class CodeAddView(generic.CreateView):
template_name = 'teladm/code_add.html'
form_class = CodeAddForm
You misunderstood one thing: You shouldn't use TextField to populate ForeignKey, because django foreign keys are populated using dropdown/radio button to refer to the id of the object in another model. The error you got means you provided wrong information that doesn't match any id in another model(Person in your case).
What you can do is: not using ModelForm but Form. You might have some extra work to do after you call form.is_valid(), but at least you could code up your logic however you want.
I defined a Question model with a description and a foreign key.
class Question(models.Model):
user = models.ForeignKey(
User,
verbose_name="User",
default=None
)
description = models.CharField(
max_length=60,
#verbose_name=_("Description"),
)
After that, I ran the migrations.
Then, in views.py I created a method which accesses objects of this model:
def own_questions(request):
questions = Question.objects()
return JsonResponse(questions)
The problem is that when I access the URL /questions corresponding to this method, I get:
NameError at /questions/
global name 'Question' is not defined
Why is this happening?
Probably because you haven't imported
from .models import Question
into your views.py
You need to import Questions in your views.py:
from app.models import Question
Also, questions = Question.objects only give you the queryset manager and you can't call that, instead for all questions, you need:
questions = Question.objects.all()
Edit:
I shouldn't assume what you are trying to query from model Question, so here's django doc about how to write ORM for queries.
I'm having some trouble with a Django project I'm working on. I now have two applications, which require a fair bit of overlap. I've really only started the second project (called workflow) and I'm trying to make my first form for that application. My first application is called po. In the workflow application I have a class called WorkflowObject, which (for now) has only a single attribute--a foreign key to a PurchaseOrder, which is defined in po/models.py. I have imported that class with from po.models import PurchaseOrder.
What I'm trying to do is have a page where a user creates a new PurchaseOrder. This works fine (it's the same form that I used in my PurchaseOrder application), and then uses that instance of the class to create a WorkflowObject. The problem now, is that I get the error: ValueError: Cannot create form field for 'purchase' yet, because its related model 'PurchaseOrder' has not been loaded yet. I'm really not sure where to start with this. It was working ok (allowing me to create a new PurchaseOrder and forward to a url with its primary key in the url) until I added the view that should allow me to create a new WorkflowObject. I'll put that specific view here:
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django_tables2 import RequestConfig
from po.models import PurchaseOrderForm, PurchaseOrder
from workflow.models import POObject, WorkflowForm
def new2(request, number):
po=PurcchaseOrder.objects.get(pk=number)
if request.method == 'POST':
form = WorkflowForm(request.POST)
if form.is_valid():
new_flow = form.save()
return HttpResponse('Good')
else:
return render(request, 'new-workflow.html', {'form': form, 'purchase': po})
else:
form = WorkflowForm()
return render(request, 'new-workflow.html', {'form': form, 'purchase': po})
The lines of code that seem to be causing the error (or at least, one of the lines that is shown in the traceback) is:
class WorkflowForm(ModelForm):
purchase = forms.ModelChoiceField(queryset = PurchaseOrder.objects.all())
EDIT:
I seem to have made a very noob mistake, and included parentheses in my definition of WorkflowObject, that is, I had said purchase=models.ForeignKey('PurchaseOrder'), instead of purchase=models.ForeignKey(PurchaseOrder)
I had a similar problem and was able to resolve this by declaring all my modelForm classes below all my class models in my models.py file. This way the model classes were loaded before the modelForm classes.
Firstly, you can try reduce code to:
def new2(request, number):
po=PurcchaseOrder.objects.get(pk=number)
form = WorkflowForm(request.POST or None)
if form.is_valid():
new_flow = form.save()
return HttpResponse('Good')
else:
return render(request, 'new-workflow.html', {'form': form, 'purchase': po})
Secondly, I not understood why you at other case wrote forms.ModelChoiceField(...) and another case ModelForm instance forms.ModelForm ?
Seems, that there are nothing special in your WorkflowForm, so you can define it as follows:
class WorkflowForm(ModelForm):
class Meta:
model = WorkflowObject
Field for relation will be created automatically.
Documentation: Creating forms from models
Just ran into this problem. I had a string value in the to= value of a ForeignKey (intentionally). The error was thrown because I changed my app's name from messages to messaging (because messages conflicted with django.contrib.messages), but forgot to change the model's ForeignKey string value.
For example:
# messaging/models.py
class Thread(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
class Message(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
thread = models.ForeignKey('messages.Thread', on_delete=models.CASCADE) # <- here!
The error:
ValueError: Cannot create form field for 'thread' yet, because its related model 'messages.Thread' has not been loaded yet
The solution was simply to change:
models.ForeignKey('messages.Thread', ...
to:
models.ForeignKey('messaging.Thread', ...