Field 'id' expected a number but got 'create' - python

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')

Related

DetailView in Django, keyword 'slug'

I recently started learning Django. I want to display one news item, but when I open on the link I get an error message:
Cannot resolve keyword 'slug' into field. Choices are: NewsTitles, NewsContent, NewsSlug
Request Method: GET
Request URL: http://127.0.0.1:8000/news/nam-gravida-purus-non/
Django Version: 4.0
Exception Type: FieldError
views.py
from django.views.generic import DetailView
from .models import News
class GetNews(DetailView):
model = News
slug_url_kwarg = 'NewsSlug'
template_name = 'news/single_news.html'
context_object_name = 'single_news'
allow_empty = False
urls.py
from django.urls import path
from .views import GetNews
urlpatterns = [
path('news/<str:NewsSlug>/', GetNews.as_view(), name='news'),
]
models.py
from django.db import models
from django.urls import reverse_lazy
class News(models.Model):
NewsTitles = models.CharField(max_length=120)
NewsContent = models.TextField(max_length=255)
NewsSlug = models.SlugField(max_length=255)
def __str__(self):
return self.NewsTitles
def get_absolute_url(self):
return reverse_lazy('news', kwargs={'NewsSlug': self.NewsSlug})
What am I doing wrong?
First of all do not call your slug "NewSlug" with uppercase but all lower case "newslug" or even better "new_slug", the name itself should be more descriptive as well.
Finally you need to tell your view which field to use, you can define that with the following attribute :
slug_field = "NewSlug"
Note : Attribute of a class should not be camel case but snake case

django custom blog post urls

I am learning django by building a simple blogging app. While its all but done, I currently have individual posts having a url in the format https://my_site_dot_com/blog/entry/38/ where the number 38 corresponds to the primary key of said post.
What i want is it to have the format https://my_site_dot_com/blog/entry/this_is_custom_title/ where "this_is_custom_title" corresponds to the heading of the post. I have no idea how to accomplish this. Can anyone offer any assistance?
My model looks like:
class Entry(models.Model):
entry_title = models.CharField(max_length=50)
entry_text = models.TextField()
image = models.FileField(upload_to="media", blank=True)
entry_date = models.DateTimeField(auto_now_add=True)
entry_author = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "blog"
def __str__(self):
return self.entry_title
I want the entry_title to the the custom url instead of the primary key.
My urls.py looks like this:
urlpatterns = [
path('', HomeView.as_view(), name="blog-home"),
path('entry/<int:pk>/', EntryView.as_view(), name="entry-detail"),
path('create_entry/', CreateEntryView.as_view(success_url='/'), name='create_entry'),
]
Edit:
The class handing the post looks like this:
class EntryView(DetailView):
model = Entry
template_name = 'blog/entry_detail.html'
data_set = random_info()
stuff_for_post = {
"info": data_set
}
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['rand_im'] = random_image()
context['tags'] = ['tag1','tag2','tag3']
return context
I'm an absolute noob in django and come from android/java. So please give an easy to understand explanation.
Thanks in advance
You may add a slug field to your Entry model and a get_absolute_url method. Don't forget to import reverse function from Django's url module.
from django.urls import reverse
class Entry(models.Model):
entry_title = models.CharField(max_length=50)
entry_text = models.TextField()
image = models.FileField(upload_to="media", blank=True)
entry_date = models.DateTimeField(auto_now_add=True)
entry_author = models.ForeignKey(User, on_delete=models.CASCADE)
slug = models.SlugField()
def get_absolute_url(self):
return reverse('entry_detail', kwargs={'slug': self.slug})
class Meta:
verbose_name_plural = "blog"
def __str__(self):
return self.entry_title
Then, within the urls.py module of your app, add the following url pattern to the urlpatterns list. Don't forget to load the corresponding view, I guess it may be EntryView in this case.
from django.urls import path
from .views import EntryView
urlpatterns = [
...
path('<slug:slug>', EntryView.as_view(), name='entry_detail'), # new
...
]
Then the slug should replace the primary key pattern in the url.
To go a bit further, you can use a method within your model that slugify your title for instance. (define the method within the model then call it from the save method of the model, by overriding the save method)
https://docs.djangoproject.com/en/3.0/ref/utils/#django.utils.text.slugify
Currently you are passing an integer through your url. All you need to do is modify this slightly to pass a string through the url. Here is a similar question that discusses how to accomplish this.
As for changes you need to make in your code, urls.py will need to be updated
path('entry/<str:title>/', EntryView.as_view(), name="entry-detail")
You haven't provided your blog post view, but it will then look something like this:
def post(request, title):
template = "template.html"
post = Posts.objects.filter(entry_title==title)
return render(request, template, {'post':post})
If you are using a Class Based View you should use a slug.
First add a new field entry_slug to your Entry model and override the save method in order to automatically generate the entry_slug field:
class Entry(models.Model):
entry_title = models.CharField(max_length=50)
entry_slug = models.CharField(max_length=50)
...
def save(self, *args, **kwargs):
self.entry_slug = slugify(self.entry_title )
super(Entry, self).save(*args, **kwargs)
You can do by replacing the pk with entry_slug:
path('entry/<slug:entry_slug>/', EntryView.as_view(), name="entry-detail")

Difference between NestedStackedInline and NestedTabularInline

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

Nested Inline in Django Admin

I have the following scenario where there are three models as follows which should be displayed nested in DJango admin. Am using Django 1.6 release and applied settings as put up in https://github.com/Soaa-/django-nested-inlines
However, it didnt turn up with the expected output. Is there any other solutions to implement nested inlines in Django. I'm a newbie to this framework. Kindly guide me to fix this issue.
model.py
class Project(models.Model):
name = models.CharField(max_length=200)
code = models.IntegerField(default=0)
def __unicode__(self):
return self.name
class Detail(models.Model):
project = models.ForeignKey(Project)
value = models.DecimalField(max_digits=5, decimal_places=2)
location = models.IntegerField(default=0)
class Configuration(models.Model):
detail = models.OneToOneField(Detail)
content1 = models.IntegerField()
content2 = models.IntegerField()
admin.py
from django.contrib import admin
from nested_inlines.admin import NestedModelAdmin, NestedTabularInline, NestedStackedInline
from myapp.models import Project, Detail, Configuration
class ConfigInline(NestedStackedInline):
model = Configuration
extra = 1
class DetailInline(NestedTabularInline):
model = Detail
inlines = [ConfigInline,]
extra = 1
class ProjectAdmin(admin.ModelAdmin):
inlines = [DetailInline]
admin.site.register(Project, ProjectAdmin)
try https://pypi.python.org/pypi/django-nested-inline .
It has been updated to work with Django 1.6
I believe you've forgotten to set the ProjectAdmin as a NestedModelAdmin:
admin.py :
from django.contrib import admin
from nested_inlines.admin import NestedModelAdmin, NestedTabularInline, NestedStackedInline
from myapp.models import Project, Detail, Configuration
class ConfigInline(NestedStackedInline):
model = Configuration
extra = 1
class DetailInline(NestedTabularInline):
model = Detail
inlines = [ConfigInline,]
extra = 1
class ProjectAdmin(NestedModelAdmin):
inlines = [DetailInline]
admin.site.register(Project, ProjectAdmin)
Before you import this below package first install this
pip install django-nested-admin
then add this in installed app list
INSTALLED_APPS = [
...
'nested_admin',
...
]
Now, you can import it.
from nested_inline.admin import NestedModelAdmin, NestedTabularInline, NestedStackedInline

Django ModelAdmin extra input field not from Model

I'm trying to add an extra input to a admin.ModelAdmin for a model I have so I can record some optional text when another input has changed.
I can't get the custom ModelForm recognised as name 'EquipmentAdmin' is not defined. I've tried several different ways of importing but think I must have missed something obvious. It feels like there's a circular reference between the EquipmentAdmin and EquipmentAdminForm as they both include a reference to each other in the code.
I have created my Django application Flightdeck and have these all in the same folder;
models.py
from django.db import models
class Location(models.Model):
name = models.CharField(max_length=45)
class Equipment(models.Model):
unit_id = models.CharField(max_length=45)
located = models.ForeignKey(Location)
located_from = models.DateField()
class EquipmentLocationHistory(models.Model):
unit = models.ForeignKey(Equipment)
located = models.ForeignKey(Location)
start = models.DateField()
end = models.DateField()
change_reason = models.CharField(max_length=45)
admin.py
from django.contrib import admin
from flightdeck.models import *
from flightdeck.forms import EquipmentAdminForm
class EquipmentAdmin(admin.ModelAdmin):
form = EquipmentAdminForm
def save_model(self, request, obj, form, change):
if 'located' in form.changed_data:
try:
old = Equipment.objects.get(unit_id=obj.unit_id)
except Equipment.DoesNotExist:
old = None
if old:
if 'located' in form.changed_data:
located_history = EquipmentLocationHistory(unit=obj, located=old.located, start=old.located_from, end=obj.located_from)
located_history.save()
obj.save()
forms.py
from django import forms
from django.contrib import admin
class EquipmentAdminForm(forms.ModelForm):
reason = forms.CharField()
class Meta:
model = EquipmentAdmin
I would like to include the reason value when I add the EquipmentLocationHistory but can't test what I have as the EquipmentAdminForm isn't loaded.
EquipmentAdmin is not a model. Your ModelForm needs to reference Equipment
from django import forms
from django.contrib import admin
from flightdeck.models import Equipment
class EquipmentAdminForm(forms.ModelForm):
reason = forms.CharField()
class Meta:
model = Equipment
PS: when you have circular references, there are many ways around the problem. The best way with model imports and django is to use django.db.models.get_model('app', 'model')

Categories

Resources