Форум сайта python.su
Создаю сайт в первый раз на Django. С помощью одного ютуб канала, делаю всё как по видео. Но в итоге, не могу уже пару дней понять свою ошибку. Я с помощью миксина хочу сделать так, что бы я мог обновить свой Post. Я это сделал, в итоге я могу зайди в созданный Post, его отредактировать, но в итоге у меня создаётся новый Post, и тот что я редактировал - не удаляется. Хочу понять где у меня ошибка, что бы у меня всё правильно редактировалось, а не создавало новые посты и сохраняло прошлый. Спасибо.
post_update.html
{% extends 'dota2/wrapper.html' %} {% block title %} Edit - {{ post.title }} {% endblock %} {% block content %} <form action="{{ post.get_update_url}}" method="post"> {% csrf_token %} {% for field in form %} <div class='form-group'> {% if field.errors %} <div class='alert alert-danger'> {{ field.errors }} </div> {% endif %} {{ field.label }} {{ field }} </div> {% endfor %} <button type="submit" class='btn btn-primary' >Update Post</button> </form> {% endblock %}
from django.urls import path, include from .models import Post from .views import * urlpatterns = [ path('', posts_list, name='post_list_url'), path('post/<str:slug>/', PostDetail.as_view(), name="post_detail_url"), path('post/<str:slug>/update/', PostUpdate.as_view(), name="post_update_url"), path('create/', PostCreate.as_view(), name='post_create_url'), ]
from django.db import models from django.shortcuts import reverse from django.utils.text import slugify from time import time def gen_slug(s): new_slug = slugify(s, allow_unicode=True) return new_slug + '-' + str(int(time())) class Post(models.Model): title = models.CharField(max_length=120, db_index=True) slug = models.SlugField(max_length=150, unique=True) body = models.TextField(blank=True, db_index=True) date = models.DateTimeField(auto_now_add=True) #images = models.ImageField(upload_to='main/static/main/accsimages/', blank=True, verbose_name='подпись') #images = models.ImageField(upload_to='main/static/main/accsimages/', blank=True, height_field=None, width_field=None, max_length=100) def get_absolute_url(self): return reverse('post_detail_url', kwargs={'slug': self.slug}) def get_update_url(self): return reverse('post_update_url', kwargs={'slug': self.slug}) def save(self, *args, **kwargs): if not self.id: self.slug = gen_slug(self.title) super().save(*args, **kwargs) def __str__(self): return self.title
from django.shortcuts import render from django.shortcuts import redirect from django.shortcuts import get_object_or_404 from django.views.generic import ListView, CreateView, UpdateView from .models import * class ObjectDetailMixin: model = None template = None def get(self, request, slug): #post = Post.objects.get(slug__iexact=slug) obj = get_object_or_404(self.model, slug__iexact=slug) return render(request, self.template, context={self.model.__name__.lower():obj}) class ObjectCreateMixin: model_form = None template = None def get(self, request): form = self.model_form() return render(request, self.template,context={'form': form}) def post(self, request): bound_form = self.model_form(request.POST) if bound_form.is_valid(): new_obj = bound_form.save() return redirect(new_obj) return render(request, self.template, context={'form': bound_form}) class ObjectUpdateMixin: model = None model_form = None template = None def get(self, request, slug): obj = self.model.objects.get(slug__iexact=slug) bound_form = self.model_form(instance=obj) return render(request, self.template, context={'form': bound_form, self.model.__name__.lower(): obj}) def post(self, request, slug): obj = self.model.objects.get(slug__iexact=slug) bound_form = self.model_form(request.POST, instance=obj) if bound_form.is_valid(): new_obj = bound_form.save() return redirect(new_obj) return render(request, self.template, context={'form': bound_form, self.model.__name__.lower(): obj})
from django.shortcuts import render from django.shortcuts import redirect from django.shortcuts import get_object_or_404 from django.views.generic import ListView, CreateView, UpdateView, View from .models import Post from .forms import PostForm from .utils import * def posts_list(request): posts = Post.objects.all() return render(request, 'dota2/posts.html', context={'posts': posts}) class PostCreate(View): def get(self, request): form = PostForm() return render(request, 'dota2/post_create.html', context={'form':form}) def post(self, request): bound_form = PostForm(request.POST) if bound_form.is_valid(): new_post = bound_form.save() return redirect(new_post) return render(request, 'dota2/post_create.html', context={'form', bound_form}) class PostDetail(ObjectDetailMixin, View): model = Post template = 'dota2/post_detail.html' # def get(self, request, slug): # post = get_object_or_404(Post, slug__iexact=slug) # return render(request, 'dota2/post_detail.html', context={'post':post}) class PostUpdate(ObjectUpdateMixin, View): model = Post model_form = PostForm template = 'dota2/post_update.html'
Отредактировано barzini (Авг. 9, 2019 21:13:42)
Офлайн
barzini
Хочу понять где у меня ошибка
barziniОшибка очевидна, она коренится в методологии изучения предмета.
Создаю сайт в первый раз на Django. С помощью одного ютуб канал
Офлайн
FishHook
Ошибка очевидна, она коренится в методологии изучения предмета.
Вот есть фреймворк Django, его создавали для внутренних нужд компании, но впоследствии решили, что а почему бы и не открыть свои разработки миру? Разрабы написали документацию, создали тематический сайт, сделали туториал. Это все есть и доступно по ссылке, вы не поверите, https://www.djangoproject.com/. Любой, кто желает получить информацию о джанге может получить её там и только там. Кто такой хрен на ютубе - неведомо. Зачем нужен его канал, когда есть оригинальная документация разжеваная в пыль - неясно.
Понимаете, чтобы ответить на ваш вопрос, надо сначала вслед за вами посмотреть этот канал, чтобы вообще понять на кой черт вы городите какие-то миксины, кто вас этому научил и что у вас обоих теперь в голове.
Офлайн
barzini
Отлично! Вы пришли за советом, заметьте никто вам ничего не должен. Совет вы получили, нравится он вам или нет - я не обязан соответствовать вашим ожиданиям, а вы не имеете никакого морального права хамить в ответ и оскорблять. Я вообще то потратил на вас время, и с вашей стороны ожидается благодарность, а не хамство.
Теперь по делу.
1.
barziniВы делаете то, что уже давно сделано. Все ваши миксины есть в составе CBV джанги. Прошу все таки переступить через себя поглядеть таки в документацию, которую как вы говорите читали https://docs.djangoproject.com/en/2.2/topics/class-based-views/.
Я делаю, так как мне лучше
Офлайн
FishHook
barziniОтлично! Вы пришли за советом, заметьте никто вам ничего не должен. Совет вы получили, нравится он вам или нет - я не обязан соответствовать вашим ожиданиям, а вы не имеете никакого морального права хамить в ответ и оскорблять. Я вообще то потратил на вас время, и с вашей стороны ожидается благодарность, а не хамство. Теперь по делу. 1.
from django import forms from .models import Post from django.core.exceptions import ValidationError class PostForm(forms.ModelForm): #title = forms.CharField(max_length=50) #slug = forms.CharField(max_length=50) #body = forms.CharField(max_length=500) #bootstrap стиль до формы создания поста #title.widget.attrs.update({'class': 'form-control'}) #slug.widget.attrs.update({'class': 'form-control'}) #body.widget.attrs.update({'class': 'form-control'}) class Meta: model = Post fields = ['title', 'slug', 'body'] widgets = { 'title': forms.TextInput(attrs={'class':'form-control'}), 'slug': forms.TextInput(attrs={'class':'form-control'}) } def clean_slug(self): new_slug = self.cleaned_data['slug'].lower() if new_slug == "create": raise ValidationError('Slug may not be "create"') if Post.objects.filter(slug__iexact=new_slug).count(): raise ValidationError('Slug must be unique!') return new_slug def save(self): new_post = Post.objects.create(title=self.cleaned_data['title'], slug=self.cleaned_data['slug'], body=self.cleaned_data['body']) return new_post
Офлайн
def save(self): new_post = Post.objects.create(title=self.cleaned_data['title'], slug=self.cleaned_data['slug'], body=self.cleaned_data['body']) return new_post
barziniВсё что делает ваш метод save у формы - создает новый объект. Собственно, чего другого вы ожидаете?
но в итоге у меня создаётся новый Post, и тот что я редактировал - не удаляется
barziniВо-первых, чтобы редактировалось, надо получить существующий объект, изменить у него нужные поля и сохранить его в базу. Ваша форма принудительно создает новый объект.
Как сделать так, что бы не просило изменить slug, и нормально редактировалось
Офлайн
FishHook
Во-первых, чтобы редактировалось, надо получить существующий объект, изменить у него нужные поля и сохранить его в базу. Ваша форма принудительно создает новый объект.
Во-вторых, в Джанге принято идентифицировать объекты по pk, а slug нужен для SEO, не стОит использовать его для идентификации объекта, потому что slug в отличие от pk (то есть id) может изменяться, да и вообще как мне кажется держать индекс на varchar так себе затея.
Офлайн