I have an app with lots of class based views. In some of my ListViews, the items recently created are not being displayed. My models are like:
# models.py
class Parent(models.Model):
name = models.CharField(max_length=10)
class Child(models.Model):
parent = models.ForeignKey(Parent)
name = models.CharField(max_length=10)
And
# views.py
class ChildListView(ListView):
model = Child
template = 'child.html'
The thing is that, whenever I create an object from a CreateView, it doesn't appear in my list view. I thought it was because of sqlite in my developing server, but it happens also in MySQL. If I restart the service, it works normally. Any idea?
Related
I using a nested model in a Django project.
The following snippet code is models.py:
from django.db import models
from django.db.models.deletion import CASCADE
class Model_(models.Model):
name = models.CharField(max_length=50, default="This is a model")
frequently = models.FloatField(default=1.0)
def __str__(self):
return self.name
class SubModel(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=8, default='0x')
model_ = models.ForeignKey(Model_, on_delete=CASCADE)
def __str__(self):
return self.name
class Metadata(models.Model):
key = models.CharField(max_length=100)
value = models.CharField(max_length=100)
sub_model = models.ForeignKey(SubModel, on_delete=CASCADE)
This is my admin.py script:
from django.contrib import admin
from nested_inline.admin import NestedTabularInline, NestedStackedInline,\
NestedModelAdmin
from <djano-application-name>.models import Model_, SubModel, Metadata
class MetadataAdmin(NestedTabularInline):
model = Metadata
extra = 1
class SubModelAdmin(NestedStackedInline):
model = SubModel
inlines = [MetadataAdmin]
extra = 1
class Model_Admin(NestedModelAdmin):
model = Model_
inlines = [SubModelAdmin]
list_display = ['name']
admin.site.register(Model_, Model_Admin)
Question:
What is the difference between NestedStackedInline and NestedTabularInline in admin.py script?
[NOTE]:
Versions: Python 2.7 and Django 1.11
If you are using django-nested-inline, It means you wanted to edit models on the same page as a parent model and add more than 1 level of children at once with the parent object in admin.
The Django admin is just a normal Django application and you can't have a second level of inlines(nested forms) in the default Django admin.
The difference between NestedStackedInline and NestedTabularInline is just Layout. Indeed, both work exactly the same behind the scenes, the only difference is the template used for rendering. Check the official docs. So, picking one for your project is only a matter of preference regarding the interface layout.
This is how NestedStackedInline will look, each field of the model is under other.
and this is NestedTabularInline, each field of the model is in one line, column wise
I'm trying to integrate two django apps where each had their individual auths working. To do that, I'm trying to subclass AbstractUser instead of User. I'm following the PyBB docs and Django#substituting_custom_model. I've removed all migration files in all my apps apart from their individual init.py (including the migrations from the PyBB library sitting in my site-packages). I've also changed the Mysql database to a blank one to start afresh and I'm trying to subclass AbstractUser as shown below.
My Models.py:
from django.contrib.auth.models import User
from django.contrib.auth.models import AbstractUser
from django.db import models
class Student_User(models.Model):
"""
Table to store accounts
"""
su_student = models.OneToOneField(AbstractUser)
USERNAME_FIELD = 'su_student'
su_type = models.PositiveSmallIntegerField(db_column='su_type', default=0)
su_access = models.TextField(db_column='su_access', default='')
su_packs = models.TextField(db_column='su_packs', default='')
REQUIRED_FIELDS = []
def __unicode__(self):
return str(self.su_student)
My settings.py:
AUTH_USER_MODEL = "app.Student_User"
PYBB_PROFILE_RELATED_NAME = 'pybb_profile'
When running makemigrations for my primary app, I get this error:
app.Student_User.su_student: (fields.E300) Field defines a relation with model 'AbstractUser', which is either not installed, or is abstract.
How do I achieve what I am trying to do here?
PS: The app was working fine with onetoone with User without username_field or required_field.
PPS: I just checked the AbstractUser model in my contrib.auth.models and it has class Meta: abstract = True. Ok so its abstract, still, how do I resolve this? I just need one login, currently, two parts of my site, although connected through urls, ask for seperate logins and dont detect each others logins. What do I need to do for this?
You can't have a one-to-one relationship with an abstract model; by definition, an abstract model is never actually instantiated.
AbstractUser is supposed to be inherited. Your structure should be:
class Student_User(AbstractUser):
...
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 have a Django (1.8) Model for an underlying database table that has multiple columns that are logically a fixed-size array. For example:
from django.db import models
class Widget(models.Model):
# ...
description_1 = models.CharField(max_length=255)
description_2 = models.CharField(max_length=255)
description_3 = models.CharField(max_length=255)
# ...
I would like to be able to access these columns as if they were a collection on the model instance, e.g.:
instance = Widget.objects.get(...)
for description in instance.descriptions:
# do something with each description
My primary motivation is that I am exposing this model via Django Rest Framework (DRF), and would like the API clients to be able to easily enumerate the descriptions associated with the model. As it stands, the clients have to reference each logical 'index' manually, which makes the code repetitive.
My DRF serializer code is currently like this:
class WidgetSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Widget
There are a fixed number of descriptions for each Widget, and their ordering is important.
Is there a clean way to expose these fields as a collection on the Model object?
It really was as easy as adding a method to the Model class that returns the fields as a sequence, and then (for API clients), manually specifying that new method as a field to serialize.
So the Model definition becomes:
from django.db import models
class Widget(models.Model):
description_1 = models.CharField(max_length=255)
description_2 = models.CharField(max_length=255)
description_3 = models.CharField(max_length=255)
def descriptions(self):
return self.description_1, self.description_2, self.description_3
And the DRF serializer is updated like:
class WidgetSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Widget
fields = ('url', 'descriptions',)
This causes the API to return a JSON array for descriptions and omit all of the individual description_x fields.
I installed app https://github.com/zerok/django-flatblocks, next I want to extend this app model https://github.com/zerok/django-flatblocks/blob/master/flatblocks/models.py. New models.py looks
class MyFlatBlock(FlatBlock):
my_field = models.CharField()
How can I do this, whitout coping all app (django-flatblocks) to my project and rewrite this model?
Create another model
class MyFlatBlock(models.Model):
flat_block = models.OneToOneField(FlatBlock, related_name='extra')
my_field = models.CharField()
Then you will be able to use flatblock.extra.my_field (catching AttributeError if necessary).