So I want to make it so a "Tutor" can select a "Student", now each tutor has a different set of Students so the drop down list needs to be unique.
So this is the part of forms where question comes from, tutor1 get's passed through by response into views, then from views it needs to be passed into the form so Students.objects.all displays all of the students that tutor1 has. (The query set part is fine and I believe the Field is also correct) the part that doesn't work is passing in response or passing in the tutor1 into the form and so far I can't find anywhere how to do this.
student = forms.ModelChoiceField(queryset = Students.objects.all(tutor=tutor1.id))
This is the last piece of the hard part of my website so I'd be so grateful if anyone knows how to fix this.
Nevermind think I found an answer, you can't haha. But the strategy instead is using class based views.
https://medium.com/analytics-vidhya/django-how-to-pass-the-user-object-into-form-classes-ee322f02948c
This page explains it really well.
Related
Example: Car Website.
If you have a URL structure that goes like this /maker/model/year. Where maker, model, year are the generic default placeholder for any. And replace any part will filter the results.
So:
/maker/ will list give you a list of car makers like VW or Ford.
/Ford/model/ will list all models made by Ford
/maker/model_of_car/ will list all models with that name (if two makers have the same name of the model it will list both.
/maker/model/ will list all models
etc... if you need more example please say. But I hope this is enough to get the idea across.
What is the optimal number of URLs need to cover all possibility? Can you show if not all, a critical number of example to get the idea across. So in the form url(r'(?P<maker>[w-]+)/(?P<model>[w-]+/)' (optimal meaning: NOT making just making one super URL that will require a complex view and template to make it work.)
I am sorry about the question name, can someone change it to fit the body (if required). I feel like it does not do the body justice.
Thank you for your time.
I believe this will work for your needs, but I think you should rethink your url convention. Look at how Django Rest Framework builds it's ViewSet's urls. it will work great for you
url(r'^maker/$', <view>),
url(r'^maker/model/$', <view>),
url(r'^maker/(?P<model_of_car>[\w ]+)/$', <view>),
url(r'^(?P<maker>[\w ]+)/model/$', <view>),
I'm new in Django and I'm giving myself a big headhache trying to structure this query.
I have a BaseProfile connected with a OneToOne field to User.
I'm specializing the profile in CustomerProfile connected with a OneToOne field to BaseProfile.
A CustomerProfile has a ManyToMany relationship with other CustomerProfile (so itself) through a RelatedCustomer model.
In the RelatedCustomer I specify the from_customer and to_customer Foreign Keys.
Maybe with an image you can understand better.
My problem:
Given a user.id I need to know all the other user.id of the customers that he is connected to (so passing through from_customer and to_customer):
So basically, first I need to dig from User to RelatedCustomer using reverse lookup, take all the set, and then going back to know the user.id of each customer in the set.
EDIT2:
What I've reached so far:
# This gives me back a customer profile given a user.id (2)
cm = CustomerProfile.objects.get(base_profile__user=2)
# M2M lookup. Given one customer returns all the RelatedCustomer relations
# that he has as a part of the 'from' M2M
cm.from_photographer.all()
Chaining the previous two: given a user.id I obtain a queryset of CustomerRelated relations:
rel = CustomerProfile.objects.get(base_profile__user=2).from_photographer.all()
This gives me back something like:
[<CustomerRelated: from TestCustomer4 to TestCustomer2 >,
<CustomerRelated: from TestCustomer4 to TestCustomer3 >]
Where in this case the user having a user.id=2 is the TestCustomer4.
My question:
So far so good, but now having this set how can I get all the user.id of the to_customer?
That is, how do I get the user.id of TestCustomer2 and TestCustomer3?
Firstly, this is not how you query the database in django. Secondly (since you're learning), it would be good to point out that you can run dbshell to try out different things. And lastly, this kind of problem is described in the documentation.
I am telling you this, because as a beginner, I also felt that it was a little difficult to navigate through the whole thing. The best way to find things is just to use google, and add a django at the end.
I know how you feel, the documentation search sucks, right? Heh, I feel you, that is why you always search the way I described it. Once you get a hang of the documentation, you will feel that the documentation title page is a little more intuitive.
Okay, so now to the answer:
To access a ManyToMany, OneToOne or ForeignKey field, you need to use a __ commonly known as dunder.
So, this is how I would go about doing this. Please note that there are other ways, and potentially better ways of doing this:
thing_I_want = RelatedCustomer.objects.get(to_customer__id=2)
Note, however that if you wanted to get a list of customers you would use filter(). Here is an example (which uses number of purchases as an example):
things_I_want = RelatedCustomer.objects.filter(to_customer__no_of_purchases=16)
Also note that the great thing about filter is that you stack one filter on top of another. You can read more about these features in the documentation link I provide below.
That will get you what you want. Now, you might have more queries regarding this, and how it all works together. Not to fear, please click this documentation link to check it out.
EDIT
Seems like what you want to do can be done by django, but if you want to do it using sql, then that is possible too. For example, SomeModel.objects.raw("SQL_HERE"). The name of the tables are usually <app>_<model>.
However, what you are asking can also be done in django, using the ORM. But it will be tricky.
Ok, as usual whenever you get the answer it always look much more easier than what you were expecting.
I guess this worked for me:
User.objects.filter(base_profile__customer_profile__to_customer__in=
User.objects.get(id=2).base_profile.customer_profile.from_customer.all())
Many thanks to #Games Brainiac
I'm developing a Twitter-like system, and have a model to record who follows who. There are two fields and both fields are foreign keys and point to the User model.
Clearly you wouldn't want a follower-followee record duplicated, so I'm using the unique_together attribute in the inner Meta class, in order that the follower-followee pair is unique. Trying to violate this throws IntegrityError and 500 status code.
This feels like a "second line of defence" as my view and template code doesn't give a user the chance to follow someone twice.
Should I/can I do something similar to ensure you can't follow yourself?
The view and template that lists all users (each with a button to click to follow that user) does not list the currently logged in user, so there should be no opportunity to follow yourself. But I don't have anything equivalent to unique_together.
Dude, no.
I don't know why you're doing this, but assuming it isn't for a uni project with a lunatic professor, you're wasting your time.
That is, if he's not a lunatic he's not going to try and hack the following/followee . And so what if he does?
If its for a startup-idea, then spend less time solving this (trivial) problem and more time working on whatever business model or marketing or whathaveyou thing you need to do.
A little bug isn't going to be a show stopper.
If you're being contracted out, leave it as a bug and get the conteact extended to fix it :)
If you just want to fix this, just do a check in the model or the validation that the follower isn't the same as the followee
So let's say at the last minute (in the view) I decide I want to specify a default for a field and make it hidden, like so:
form.fields['coconut'] = forms.ModelChoiceField(
label="",
widget=forms.HiddenInput(),
queryset=swallow.coconuts.all(),
initial=some_particular_coconut,
)
My question is this: Do I really need to specify queryset here? I mean, I already know, from initial, exactly which coconut I'm talking about. Why do I also need to specify that the universe of available coconuts is the set of coconuts which this particular swallow carried (by the husk)?
Is there a way I can refrain from specifying queryset? Simply omitting causes django to raise TypeError.
If indeed it is required, isn't this a bit damp?
I think is good that stackoverflow answers point to the 'right' way to do things, but increasingly the original question goes unanswered because the user was trying to do the wrong thing.
So to answer this question directly this is what you can do:
form.fields['coconut'] = forms.ModelChoiceField(label="", widget=forms.HiddenInput(attrs={'value':some_particular_coconut}), queryset=swallow.coconuts.all())
Notice the named argument passed to HiddenInput, its super hackish but its a direct answer to the original question.
The problem is that you're trying to set up a hidden ModelChoiceField. In order to have a Choice (dropdown, traditionally) it needs to know its Choices - this is why you give a queryset.
But you're not trying to give the user a choice, right? It's a hidden input, and you're setting it from the server (so it gets POSTed back, presumably).
My suggestion is to try to find a way around using the hidden input at all. I find them a bit hacky. But otherwise, why not just specify a text field with some_particular_coconut.id, and hide that? The model's only wrapping that id anyway.
The reason django requires a queryset is because when you render the field to the page, django only sends the id. when it comes back, it needs knowlege of the queryset in order to re-inflate that object.
if you already know the queryset at form creation time, why not simply specify form.fields['coconut'].initial = some_particular_coconut in your view and leave the rest of the definition in your forms.py?
If you find that you only really need to send the id anyway (you don't have to re-inflate to an object at your end), why not send it in a char field?
I have a view that handles a POST request and attempts to create a new object. However, I know that some of the POST'd data is invalid... But I want to fix it and go ahead and create the object.
The only way I can figure out to be able to 'fix' data in a ModelForm is to create a 'is_valid()' form. To do this, I can either create the form with the POST data, or I can create it with an already existing instance. Unfortunately, if I use the POST data, because some of it is invalid, the form won't validate and I am thus unable to get to the data in the form to fix it. If I create it with an already existing instance, this works, but when the form is displayed, any remaining errors are for whatever reason ignored (and thus don't show up on the web page.) I've tried a combination of creating the the Model form from the POST data and giving it an instance, but this doesn't seem to help. Additionally, I've tried modifying (a copy of) the POST data, fixing it, and then creating the ModelForm from the 'fixed' POST data. This sort of works, with the exception that I have some ImageFields in my form, and they seem to just be ignored.
Any help would be greatly appreciated. I have looked at every good page that I can find to no avail.
Perhaps there is a better way to do this? The problem I'm trying to solve is that I want to have a model that contains ImageFields. The first time I put up the form, the user needs to 'upload' images for each of the fields. However, if he doesn't update an image for one of the fields, I want the new form to come up with a Image upload button on the fields where images have not been uploaded, and just a text field with the image name for images that have been uploaded.
Edit 9/15/2010:
Ok, I think I can simplify all of the above question into this:
def testing( request ) :
test_form = UserProfileForm()
valid = test_form.is_valid()
return render( 'testing.tmpl', locals(), request )
When the above code is rendered, the 'valid' shows as False (as one might expect), but the 'test_form' renders without any errors. I've read through (if perhaps not understood?) the documentation on Models and ModelForms, and I see that most of the time a ModelForm (in my case: UserProfileForm) is created with a specified 'instance'. However, 1) I don't have an instance yet, 2) I would still expect the non-instance'd Form to display errors. I'm sure there is something I am missing. Please illuminate. :)
One more thing, which perhaps the answer to the above will answer anyway, but as far as I can tell, the is_valid() call is supposed to call the 'clean()' function I defined for the UserProfileForm. However, (not being a python guru) I placed 'raise ValidationError()' at the top of clean(), and when I run the code, no error is shown. Thoughts?
Update: I figured out the problem and the answer is below. Thanks!
You should have a look at how to clean form fields in django. You could either manipulate the data returned from the form there or make any kind of validation!
If your ImageFields are optional then you can still validate them (that they are otherwise correct).
Then it's a matter of adjusting your template to show either the uploaded file name or an file upload field depending on whether they've already uploaded one or not. Actually, it would probably be better to give them both fields in the first case. That's what the automatic admin does (the upload field is labeled "Change").
Well, after figuring out how to use the python debugger (pdb) and the fact that within emacs it kind of 'just works' (wow!?) I was able to find that my (empty) form was not bound. Googling bound forms pointed me to this page:
http://docs.djangoproject.com/en/dev/ref/forms/api/
RTFM'ing I find that I can pass an empty dictionary to my form and then everything starts to behave as I would expect. So, to summarize, there is a big difference between:
test_form = UserProfileForm()
and
test_form = UserProfileForm( {} )
The second version causes the rendering of the form to show all the errors (and to call 'clean()').
With risk of having this deleted by the moderator ;) Thank you to all those who commented and for your patience with a new django developer.