Given this Django code in my models.py:
class ClientManager(UserManager):
def create_user(self, *args, **kwargs):
raise(Exception)
client = Super(UserManager, self).create_user(*args, **kwargs)
return client
class Client(AbstractUser):
objects = ClientManager()
How come no exception is raised when I create a Client user from the admin?
I've tried many variations on that principle, but no create_user ever seems to be used apart from the model's __init__(). Adding an exception in django.contrib.auth.models.UserManager.create_user() method also leads to the user being created without raising an exception, which seems to indicate that I'm missing something big, here.
Related
Overloading changelist_view and calling the super() causes attribute errors.
I'm creating a super basic dashboard and I am overriding the changelist_view method of a ModelAdmin class. However, this override is resulting in an error "NoneType object has no attribute 'has_header'." However, I'm literally not doing anything but override the changelist_view and calling the super class - I haven't made any changes yet.
In admin.py
class SummaryAdmin(admin.ModelAdmin):
def changelist_view(self, request, extra_context=None):
response = super().changelist_view(request, extra_context)
The corresponding model in models.py
class Summary(Failure):
class Meta:
proxy = True
verbose_name = 'Failure Summary'
verbose_name_plural = 'Failures Summary'
This is literally the entire contents of the admin model. When I try to go to the django admin panel, I get the attribute error. As far as I can tell, this should be no different than not overriding changelist_view at all, but if I delete the override everything functions as normal.
Update: I literally copied the changelist_view code from options.py rather than calling the super class and I do not get this error, so I suspect it has something to do with how I'm calling the super class.
The problem with the above code is it lacks a return statement. changelist_view returns a response, and an overload that does not return will cause all sorts of errors. This is an easy mistake to make if you're used to languages that will not let you compile if you forget your return or it does not match the stated type.
Been stuck with hard to find misbehavior. After many hours revealed it looks like Django suppresses AttributeError and possibly other exceptions:
from django import forms
class MyBaseForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('field1', 'field2', )
…
class MyForm(MyBaseForm):
def clean_field1(self):
super(MyForm, self).clean_field1() # calling non-exitsting method
# instead of AttributeError exception being raised,
# following code is not executed without a warning
return self.another_field_handler('field1')
Can anybody explain if this surprising behavior is normal for Django forms ? Some link where is it documented?
Hoi, this is my first post and I am pretty new to django.
[Edit: changed "from" to "mfrom"]
I have a generic class like
class Message(models.Model):
mfrom = models.TextField()
text = models.TextField()
def beautify(self, text):
'''replace emoticons with images'''
return text
def save(self, *args, **kwargs):
self.text = self.beautify(self.text)
super(Message, self).save(*args, **kwargs)
and I have a few sources where messages are coming from that need different handling, some (like XMPP) will come from non HTTP request sources, but external scripts.
So I thought I'd make subclasses of Message for the different types like
class MessageXMPP(Message):
def load_from_XMPP(self, xmppmsg):
self.mfrom = xmppmsg.mfrom
self.text = xmppmsg.text
class MessageJSON(Message):
def load_from_JSON(self, jsonmsg):
self.mfrom = jsonmsg.mfrom
self.text = jsonmsg.text
If I now call the save() method of the above two classes django tries to save it to the MessageXMPP resp. MessageJSON tables, while I want the data to be stored in the Message table (and not have MessageXMPP resp. MessageJSON tables created at all).
Is there a way to not create a Message object and copy the values over, but have the subclasses write to the Message table?
I don't really understand why you have separate model classes here. You should really just have one class with the different methods. Even better, since these are creation methods, you should define a custom Manager which returns the instantiated Message.
However, if you insist on having separate classes, you should make them proxy models so that they do not reference their own tables:
class MessageJSON(Message):
class Meta:
proxy = True
I'm trying to adopt the Django documentation example on using class based views with mixins in order to be able to make a simple way of downloading the objects in a list view in CSV format, but I am failing miserably and do not really see what I am doing wrong.
I have a view defined as:
class MyObjectList(CSVResponseMixin,
MultipleObjectTemplateResponseMixin,
BaseListView
):
object_type = None
def get_context_data(self, **kwargs):
object_type = self.object_type
...some code...
return context
def render_to_response(self, context, **kwargs):
if self.request.GET.get('format', '') == 'csv':
return CSVReponseMixin.render_to_response(self, context, **kwargs)
else:
return MultipleObjectTemplateResponseMixin.render_to_response(self, context, **kwargs)
the mixin is:
class CSVResponseMixin(object):
def render_to_response(self, ctx, **kwargs):
return self.HttpResponse.render_to_response(self.convert_to_csv(ctx), **kwargs)
def conver_to_csv(ctx):
return do_csv_magic(ctx)
and in urls.py the view is called as:
url(r'^list/foos/$',
MyObjectList.as_view(object_type="someobject", model=models.MyModel),
name="myobjects",
)
However when I try to access the view without the ?format=csv query, I get a TypeError
Exception Value: __init__() got an unexpected keyword argument 'request'
Exception Location: /usr/lib/python2.6/site-packages/django/views/generic/base.py in render_to_response, line 97
EDIT: I added some details to the question and ended up implementing this with a different approach, but I still want to know what I was doing wrong.
In short, you're overdoing it. I'm not sure what is your intention here, but I've learned that the best approach is to find the closest generic view to what you're trying to do and simply extend it in views.py. Examples are many, but I invite you to check my code at https://bitbucket.org/BerislavLopac/resume/src/d7cfcf9c370b/resume_app/myproject/web/views.py.
According to the docs, render_to_response only takes the following arguments: template_name, dictionary, context_instance, mimetype
Therefore within FooResponseMixin when you're calling:
self.HttpResponse.render_to_response(self.mutilate_context(ctx), **kwargs)
You're passing in extra arguments within kwargs that render_to_response doesn't accept. Either remove the **kwargs or assign only what you need from it to variables to pass in to the accepted arguments.
I have a model that I would like to contain a subjects name and their initials (he data is somewhat anonymized and tracked by initials).
Right now, I wrote
class Subject(models.Model):
name = models.CharField("Name", max_length=30)
def subject_initials(self):
return ''.join(map(lambda x: '' if len(x)==0 else x[0],
self.name.split(' ')))
# Next line is what I want to do (or something equivalent), but doesn't work with
# NameError: name 'self' is not defined
subject_init = models.CharField("Subject Initials", max_length=5, default=self.subject_initials)
As indicated by the last line, I would prefer to be able to have the initials actually get stored in the database as a field (independent of name), but that is initialized with a default value based on the name field. However, I am having issues as django models don't seem to have a 'self'.
If I change the line to subject_init = models.CharField("Subject initials", max_length=2, default=subject_initials), I can do the syncdb, but can't create new subjects.
Is this possible in Django, having a callable function give a default to some field based on the value of another field?
(For the curious, the reason I want to separate my store initials separately is in rare cases where weird last names may have different than the ones I am tracking. E.g., someone else decided that Subject 1 Named "John O'Mallory" initials are "JM" rather than "JO" and wants to fix edit it as an administrator.)
Models certainly do have a "self"! It's just that you're trying to define an attribute of a model class as being dependent upon a model instance; that's not possible, as the instance does not (and cannot) exist before your define the class and its attributes.
To get the effect you want, override the save() method of the model class. Make any changes you want to the instance necessary, then call the superclass's method to do the actual saving. Here's a quick example.
def save(self, *args, **kwargs):
if not self.subject_init:
self.subject_init = self.subject_initials()
super(Subject, self).save(*args, **kwargs)
This is covered in Overriding Model Methods in the documentation.
I don't know if there is a better way of doing this, but you can use a signal handler for the pre_save signal:
from django.db.models.signals import pre_save
def default_subject(sender, instance, using):
if not instance.subject_init:
instance.subject_init = instance.subject_initials()
pre_save.connect(default_subject, sender=Subject)
Using Django signals, this can be done quite early, by receiving the post_init signal from the model.
from django.db import models
import django.dispatch
class LoremIpsum(models.Model):
name = models.CharField(
"Name",
max_length=30,
)
subject_initials = models.CharField(
"Subject Initials",
max_length=5,
)
#django.dispatch.receiver(models.signals.post_init, sender=LoremIpsum)
def set_default_loremipsum_initials(sender, instance, *args, **kwargs):
"""
Set the default value for `subject_initials` on the `instance`.
:param sender: The `LoremIpsum` class that sent the signal.
:param instance: The `LoremIpsum` instance that is being
initialised.
:return: None.
"""
if not instance.subject_initials:
instance.subject_initials = "".join(map(
(lambda x: x[0] if x else ""),
instance.name.split(" ")))
The post_init signal is sent by the class once it has done initialisation on the instance. This way, the instance gets a value for name before testing whether its non-nullable fields are set.
As an alternative implementation of Gabi Purcaru's answer, you can also connect to the pre_save signal using the receiver decorator:
from django.db.models.signals import pre_save
from django.dispatch import receiver
#receiver(pre_save, sender=Subject)
def default_subject(sender, instance, **kwargs):
if not instance.subject_init:
instance.subject_init = instance.subject_initials()
This receiver function also takes the **kwargs wildcard keyword arguments which all signal handlers must take according to https://docs.djangoproject.com/en/2.0/topics/signals/#receiver-functions.