Найти - Пользователи
Полная версия: Помогите с обновлением Поста в Django
Начало » Django » Помогите с обновлением Поста в Django
1
barzini
Создаю сайт в первый раз на 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 %}

urls.py
      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'),
    
    ]

models.py
        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

utils.py
         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})

views.py
         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'

FishHook
barzini
Хочу понять где у меня ошибка
barzini
Создаю сайт в первый раз на Django. С помощью одного ютуб канал
Ошибка очевидна, она коренится в методологии изучения предмета.
Вот есть фреймворк Django, его создавали для внутренних нужд компании, но впоследствии решили, что а почему бы и не открыть свои разработки миру? Разрабы написали документацию, создали тематический сайт, сделали туториал. Это все есть и доступно по ссылке, вы не поверите, https://www.djangoproject.com/. Любой, кто желает получить информацию о джанге может получить её там и только там. Кто такой хрен на ютубе - неведомо. Зачем нужен его канал, когда есть оригинальная документация разжеваная в пыль - неясно.
Понимаете, чтобы ответить на ваш вопрос, надо сначала вслед за вами посмотреть этот канал, чтобы вообще понять на кой черт вы городите какие-то миксины, кто вас этому научил и что у вас обоих теперь в голове.
barzini
FishHook
Ошибка очевидна, она коренится в методологии изучения предмета.
Вот есть фреймворк Django, его создавали для внутренних нужд компании, но впоследствии решили, что а почему бы и не открыть свои разработки миру? Разрабы написали документацию, создали тематический сайт, сделали туториал. Это все есть и доступно по ссылке, вы не поверите, https://www.djangoproject.com/. Любой, кто желает получить информацию о джанге может получить её там и только там. Кто такой хрен на ютубе - неведомо. Зачем нужен его канал, когда есть оригинальная документация разжеваная в пыль - неясно.
Понимаете, чтобы ответить на ваш вопрос, надо сначала вслед за вами посмотреть этот канал, чтобы вообще понять на кой черт вы городите какие-то миксины, кто вас этому научил и что у вас обоих теперь в голове.

Я делаю, так как мне лучше. Я читал документацию, она мне не укажет на суть проблемы. Если не знаете, где скрывается ошибка, то зачем свой высер “гения” здесь подавать?
FishHook
barzini
Отлично! Вы пришли за советом, заметьте никто вам ничего не должен. Совет вы получили, нравится он вам или нет - я не обязан соответствовать вашим ожиданиям, а вы не имеете никакого морального права хамить в ответ и оскорблять. Я вообще то потратил на вас время, и с вашей стороны ожидается благодарность, а не хамство.

Теперь по делу.
1.
barzini
Я делаю, так как мне лучше
Вы делаете то, что уже давно сделано. Все ваши миксины есть в составе CBV джанги. Прошу все таки переступить через себя поглядеть таки в документацию, которую как вы говорите читали https://docs.djangoproject.com/en/2.2/topics/class-based-views/.

2. Покажите код формы.
barzini
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

Вообще проблема в том что при редактировании, когда я меняю title + body. нужно объязательно изменить и slug. В итоге при изменении, я как бы создаю новый пост. Как сделать так, что бы не просило изменить slug, и нормально редактировалось
FishHook
     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
но в итоге у меня создаётся новый Post, и тот что я редактировал - не удаляется
Всё что делает ваш метод save у формы - создает новый объект. Собственно, чего другого вы ожидаете?

barzini
Как сделать так, что бы не просило изменить slug, и нормально редактировалось
Во-первых, чтобы редактировалось, надо получить существующий объект, изменить у него нужные поля и сохранить его в базу. Ваша форма принудительно создает новый объект.
Во-вторых, в Джанге принято идентифицировать объекты по pk, а slug нужен для SEO, не стОит использовать его для идентификации объекта, потому что slug в отличие от pk (то есть id) может изменяться, да и вообще как мне кажется держать индекс на varchar так себе затея.
barzini
FishHook
Во-первых, чтобы редактировалось, надо получить существующий объект, изменить у него нужные поля и сохранить его в базу. Ваша форма принудительно создает новый объект.
Во-вторых, в Джанге принято идентифицировать объекты по pk, а slug нужен для SEO, не стОит использовать его для идентификации объекта, потому что slug в отличие от pk (то есть id) может изменяться, да и вообще как мне кажется держать индекс на varchar так себе затея.


Спасибо. Возможно с нуля буду создавать сайт. По другим учебникам

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB