I know that similar questions have been asked here in stackoverflow, but this is not just a mere question but a confirmation of my basic understanding. This is directed to those who have knowledge in Django.
My dilemma is the function admin.site.register() in admin.py in Django. My undestanding is that it accepts a number of arguments; I am playing around with it at this moment by working on the tutorials provided at the Django website. The arguments that I have at this time are Questions(model), QuestionsAdmin(admin.ModelAdmin)
and i have this admin.site.register(Question,QuestionAdmin).
the QuestionAdmin class changes the outlook of the Question Page in admin. it allows me to add, reduce the number of information that I want to be shown at the same time, edit how it looks.
However, when I tried this admin.site.register(Questions,Choice) where Choice is a model. it spits out an error.
Does this mean that admin.site.register accepts arguments:
a The Model you want to add/register
b) any classes specifically created to be of use to the model, such as functions, statements altering
the view and functionality of the model in display/view.
to add to that, when i increase the number of arguments to 3, it spits out an error saying that i have inputed 4.
is this function considering a nul value at the beginning?
Please do enlighten me O Wizards and Warlocks of Django.
For every Model (and ModelAdmin) you have, you should call register separately, for example:
admin.site.register(Question, QuestionAdmin)
admin.site.register(Choice)
The error about the 4 arguments is because register is a method of the default AdminSite instance, so the first argument is self. From the django code:
def register(self, model_or_iterable, admin_class=None, **options):
Related
I'm trying to improve my understanding of using forms in django and looking at the docs I'm confused of where the base_fields dictionary comes from in ManagementForm class?Hope someone can help me understand. Initially I thought its passed in by some other method but I cant seem to find which one.
class ManagementForm(Form):
"""
Keep track of how many form instances are displayed on the page. If adding
new forms via JavaScript, you should increment the count field of this form
as well.
"""
def __init__(self, *args, **kwargs):
self.base_fields[TOTAL_FORM_COUNT] = IntegerField(widget=HiddenInput)
self.base_fields[INITIAL_FORM_COUNT] = IntegerField(widget=HiddenInput)
Source code: https://docs.djangoproject.com/en/2.2/_modules/django/forms/formsets/#BaseFormSet
It is originally declared in the metaclass of the Form class.
For whatever reason I have found myself walking through the Django source more often than any other framework I've used, especially related to forms.
I'm trying to create a simple cropping utility using jQuery and Jcrop (would be inside a modelform).
Initially I had this in my models:
photo = CustomImageField(null=True, allowed_types=['type:image'],
width=960, height=340)
However now I have Jcrop data (that I would like to insert for 'width' and 'height' parameters) in my main.js and would have to be sent to Django.
To do that, I created a hidden form field in my modelform and I populate it with jQuery after the user has created a selection (a default is also provided, in case the user does not select anything).
I was thinking that maybe I could add the extra keyword arguments when I override the form save() method, but
a) does it pass the kwargs to the CustomImageField?
b) I have no idea (syntax-wise) how to get/add/edit the kwargs of photo.
I've tried self.fields['photo'].kwargs, self.fields['photo'].getattr('width') and many other similar constructions that I've used in the past, but none provided any results.
After some googling I stumbled upon x = kwargs.pop('y', None) (it's not the same as list.pop(), is it?), but was unable to find any documentation on that and overall I get the feeling, that when I call kwargs.pop(x, y) in the save() method, then it handles the kwargs of the save() method, no matter what I set for x and y.
A little help or a hint in the right direction would be much appreciated guys, been stuck with this for days now. :)
PS. I am well aware of django-image-cropping and also well aware of that it fails to function with some specific generic Django views.
I'm pretty novice so I'll try to explain in a way that you can understand what I mean.
I'm coding a simple application in Django to track cash operations, track amounts, etc.
So I have an Account Model (with an amount field to track how many money is inside) and an Operation Model(with an amount field as well).
I've created a model helper called Account.add_operation(amount). Here is my question:
Should I include inside the code to create the new Operation inside Account.add_operation(amount) or should I do it in the Views?
And, should I call the save() method in the models (for example at the end of Account.add_operation() or must it be called in the views?)
What's the best approach, to have code inside the models or inside the views?
Thanks for your attention and your patience.
maybe you could use the rule "skinny controllers, fat models" to decide. Well in django it would be "skinny views".
To save related objects, in your case Operation I'd do it in the save() method or use the pre_save signal
Hope this helps
Experienced Django users seem to always err on the side of putting code in models. In part, that's because it's a lot easier to unit test models - they're usually pretty self-contained, whereas views touch both models and templates.
Beyond that, I would just ask yourself if the code pertains to the model itself or whether it's specific to the way it's being accessed and presented in a given view. I don't entirely understand your example (I think you're going to have to post some code if you want more specific help), but everything you mention sounds to me like it belongs in the model. That is, creating a new Operation sounds like it's an inherent part of what it means to do something called add_operation()!
I am using the standard User model (django.contrib.auth) which comes with Django. I have made some of my own models in a Django application and created a relationship between like this:
from django.db import models
from django.contrib.auth.models import User
class GroupMembership(models.Model):
user = models.ForeignKey(User, null = True, blank = True, related_name='memberships')
#other irrelevant fields removed from example
So I can now do this to get all of a user's current memberships:
user.memberships.all()
However, I want to be able to do a more complex query, like this:
user.memberships.all().select_related('group__name')
This works fine but I want to fetch this data in a template. It seems silly to try to put this sort of logic inside a template (and I can't seem to make it work anyway), so I want to create a better way of doing it. I could sub-class User, but that doesn't seem like a great solution - I may in future want to move my application into other Django sites, and presumably if there was any another application that sub-classed User I wouldn't be able to get it to work.
Is the best to create a method inside GroupMembership called something like get_by_user(user)? Would I be able to call this from a template?
I would appreciate any advice anybody can give on structuring this - sorry if this is a bit long/vague.
First, calling select_related and passing arguments, doesn't do anything. It's a hint that cache should be populated.
You would never call select_related in a template, only a view function. And only when you knew you needed all those related objects for other processing.
"Is the best to create a method inside GroupMembership called something like get_by_user(user)?"
You have this. I'm not sure what's wrong with it.
GroupMembership.objects.filter( user="someUser" )
"Would I be able to call this from a template?"
No. That's what view functions are for.
groups = GroupMembership.objects.filter( user="someUser" )
Then you provide the groups object to the template for rendering.
Edit
This is one line of code; it doesn't seem that onerous a burden to include this in all your view functions.
If you want this to appear on every page, you have lots of choices that do not involve repeating this line of code..
A view function can call another function.
You might want to try callable objects instead of simple functions; these can subclass a common callable object that fills in this information.
You can add a template context processor to put this into the context of all templates that are rendered.
You could write your own decorator to assure that this is done in every view function that has the decorator.
I'm somewhat new to Python, Django, and I'd like some advice on how to layout the code I'd like to write.
I have the model written that allows a file to be uploaded. In the models save method I'm checking if the file has a specific extension. If it has an XML extension I'm opening the file and grabbing some information from the file to save in the database. I have this model working. I've tested it in the built-in administration. It works.
Currently when there's an error (it's not an XML file; the file can't be opened; a specific attribute doesn't exist) I'm throwing an custom "Exception" error. What I would like to do is some how pass these "Exception" error messages to the view (whether that's a custom view or the built-in administration view) and have an error message displayed like if the forms library was being used. Is that possible?
I'm starting to think I'm going to have to write the validation checks again using the forms library. If that's the case, is it possible to still use the built-in administration template, but extend the form it uses to add these custom validations?
Anything to help my confusion would be appreciated.
UPDATE:
Here's my model so far, for those who are asking, "nzb" is the XML file field.
http://dpaste.com/hold/6101/
The admin interface will use the Form you associate with your model; your own views can also use the form.
This is exactly what I'd like to do. However, I don't know how to associate my forms with my models. When ever I've created forms in the past they've always acted as their own entity. I could never get the administration views to use them while using the ModelForm class. Can you shead any light on this?
I've read over the link you gave me and it seams to be what I've done in the past, with no luck.
Getting attributes from the file, should probably be a method.
Sorry, could you please elaborate on this? A method where?
UPDATE:
It seams I've been compleatly missing this step to link a form to the administration view.
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin
This should now allow me to do the validation in a Form. However, I'm still confused about how to actually handle the validation. S.Lott says it should be a method?
The Form errors are automatically part of the administrative view.
See http://docs.djangoproject.com/en/dev/ref/forms/validation/#ref-forms-validation
You're happiest if you validate in a Form -- that's what Forms are for. The admin interface will use the Form you associate with your model; your own views can also use the form.
Getting attributes from the file, should probably be a separate method of the model class. The separate method of the model class can be used by the save() method of the model class or invoked at other times by view functions.
"I could never get the administration views to use them while using the ModelForm class."
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#form
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin
"I'm still confused about how to actually handle the validation. S.Lott says it should be a method?"
Validation in a form is done with a clean() method or a clean_somefield() method.
The "Adding custom validation to the admin" link (above) shows how to add the clean_name method to the "MyArticleAdminForm" form.
If you're still confused, trying actually typing the code from the Django web page and see what it does.
I guess the best way would be to implement a special field class that extends FileField with custom validation of the uploaded file.
The validation is implemented in the field's clean method. It should check the XML file and raise ValidationErrors if it encounters errors. The admin system should then treat your custom errors like any other field errors.
The ImageField class is a good example of special validation like this — I recommend just reading through the source.
You can provide a form that will be used by the admin site. You can then perform validations in the form code that will be displayed in the admin area.
See the docs on the admin site, and in particular the form attribute of ModelAdmin.
"I'm throwing an custom "Exception" error " - Where exactly are you throwing the exception ? In your model or in your view ?
I am confused with your question, so I am assuming that you should be asking 'Where should I catch input errors if any ? ' to yourself.
The Model and View as I see are like pieces in a small assembly line.
View/ Form validation is the first action which should be performed. If there is any issue with the input data through the forms. It should be prevented at the form level using form.is_valid() etc.
The models functionality should be to provide meta information about the entity itself apart from performing CRUD. Ideally it should not be bothered about the data it is getting for the CRUD operations.